如何知道MIDI文件何时完成OS X MusicPlayer

时间:2018-04-14 21:22:04

标签: macos midi

我希望能够播放在我的应用中作为资源包含的MIDI文件。鉴于资源名称(减去.MID)文件扩展名,我有一个非常简单的函数来执行此操作:

MusicPlayer  musicPlayer;
MusicSequence  sequence;
int MusicPlaying=0;

void PlayMusic(char *fname)
{
    OSStatus    res=noErr;

    res = NewMusicPlayer(&musicPlayer);
    res = NewMusicSequence(&sequence);
    strcpy(TmpPath, "MUSIC/");
    strcat(TmpPath, fname);
    strcat(TmpPath, ".MID");
    NSString *iName = [NSString stringWithUTF8String:TmpPath];
    NSURL   *url = [[NSBundle mainBundle] URLForResource:iName withExtension:nil];

    res = MusicSequenceFileLoad (sequence, (__bridge CFURLRef _Nonnull)(url), 0, kMusicSequenceLoadSMF_ChannelsToTracks);
    res = MusicPlayerSetSequence(musicPlayer, sequence);
    res = MusicPlayerStart(musicPlayer);

    if( res==noErr ) MusicPlaying = 1;
}

这一切都很好,花花公子,只需要很少的代码......问题是我无法弄清楚如何知道MIDI文件何时播放完毕。我已经尝试过MusicPlayerIsPlaying()(它总是在文件结束后返回true,LONG)。我已经尝试过检查MusicPlayerGetTime(),但是在MIDI结束后,时间计数仍在继续。我找不到任何方式从这个或任何其他方式获得通知,以确定实际的MIDI数据已经完成播放。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

Apple的PlaySequence example显示了如何执行此操作:

  • 您必须通过获取每个轨道的长度来确定序列的长度:

    MusicSequenceGetTrackCount(sequence, &ntracks);
    for (UInt32 i = 0; i < ntracks; ++i) {
        result = MusicSequenceGetIndTrack(sequence, i, &track);
        result = MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength,
                        &trackLength, &propsize);
        if (trackLength > sequenceLength)
            sequenceLength = trackLength;
    }
    
  • 然后等到你到达那个时间:

    while (1) {
        usleep (2 * 1000 * 1000);
        result = MusicPlayerGetTime(player, &time);
        if (time >= sequenceLength)
            break;
    }