0

我有一个适用于 iPad iOS 5 的程序,它读取 MIDI,然后在键盘上与音乐同步显示音符。它工作正常,但我正在尝试添加一个“重复部分”功能,它会一遍又一遍地重复从时间戳 A 到时间戳 B 的部分。

我已经能够让时间戳作为我的重复部分的界限,但我无法让重复正常工作。当我尝试重复一个部分时,我不再得到我的键盘动画。我感觉这个问题需要超线程,但我不确定。我已经在伪代码中概述了我想在下面做的事情。

//Start Repeat Method
while (the repeat switch is toggled) {
     Stop music player.

     Set music player to the start point of the repeat.

     while (the current play point is before the end point of the repeat) {
          Check the current play point.
     }
}
//End Repeat Method

所以基本上,我想做的是在用户点击一个开关时触发一个方法,该开关将被一遍又一遍地调用,直到他们将其关闭。在该方法中,它将停止播放器,将其设置为重复的开始,播放重复直到它看到它在重复的结尾,然后重新开始该方法。

我不认为这部分会像以前那样棘手。我遇到的另一个问题是,当我将它连接到开关时,它不允许我将其关闭,它只会永远消失。

提前感谢您的建议。

**编辑

这是我到目前为止所拥有的。它允许我循环我的部分,但我的动画正在显示,我无法与 UI 交互,我必须使用 Xcode 中的停止按钮终止程序。

- (IBAction)playRepeat:(id)sender {
     if (repeatToggle.on) {
          MusicPlayerStop(player);
          playerIsPlaying = NO;

          MusicPlayerSetTime(player, sequenceRepeatStartTime);
          moviePlayerViewController.moviePlayer.currentPlaybackTime = rollRepeatStartTime;

          MusicPlayerStart(player);
          [moviePlayerViewController.moviePlayer play];
          playerIsPlaying = YES;

          float difference = rollRepeatEndTime - rollRepeatStartTime;
          [NSThread sleepForTimeInterval:difference];

          MusicPlayerStop(player);
          playerIsPlaying = NO;
          [moviePlayerViewController.moviePlayer pause];

          [self playRepeat:sender];
     }
     else if (!repeatToggle.on) {
          MusicPlayerStop(player);
          playerIsPlaying = NO;
     }
}
4

1 回答 1

2

您的while循环会耗尽 CPU,因为它一直在运行并且什么也不等待。将它放在单独的线程中可能会有所帮助,但如果您的播放器不是线程安全的,您将需要锁定机制。

并不是说没有玩家本身的通知,就很难在正确的时间重复它。您应该检查您的 MIDI 播放器是否支持任何通知或委托回调,当播放达到您指定的点时,您可以使用这些通知或委托回调来获得通知。

无论如何,我会提供可能适合您的出路。您可以使用计时器检查播放器,可能每 100 毫秒通过执行类似的操作。

-(void) repeatCheck {
    if (the repeat switch is ON) {
        if (the current play point is NOT before the end point of the repeat) {
            Stop music player.
            Set music player to the start point of the repeat.
        }
    }
    [self performSelector:_cmd withObject:nil afterDelay:0.1];
}

-(IBAction) repeatSwitchToggled {
    if (the repeat switch is ON) {
        [self repeatCheck];
    }
    else {
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(repeatCheck) object:nil];
    }
}
于 2012-06-02T02:37:19.003 回答