我有一个midi文件循环(使用MusicPlayer)并遵循回调过程

static void MyMIDIReadProc(const MIDIPacketList *pktlist,
                       void *refCon,
                       void *connRefCon) {

AudioUnit *player = (AudioUnit*) refCon;

const MIDIPacket *packet = &pktlist->packet[0];

for (int i=0; i < pktlist->numPackets; i++) {
    Byte midiStatus = packet->data[0];
    Byte midiCommand = midiStatus >> 4;

    NSMutableString *hex = [NSMutableString stringWithCapacity:10];
    for (int i=0; i < 10; i++) {
        [hex appendFormat:@"%02x ", packet->data[i]];

    }
    NSLog(hex);

    if (midiCommand == 0x09) {
        Byte note = packet->data[1] & 0x7F;
        Byte velocity = packet->data[2] & 0x7F;
        OSStatus result = noErr;
        result = MusicDeviceMIDIEvent (player, midiStatus, note, velocity, 0);

    }
    packet = MIDIPacketNext(packet);
}
}
NSLog(hex)仅向我显示以90(注解),b0(控制器),e0(弯音)或c0(程序更改)开头的数据包。那么,回调函数是否根本无法获得跟踪结束标记-FF 2F 00-还是我在这里错过了什么?我想在每次循环重新开始时得到通知。

这是我注册回调的方式:
MIDIClientRef virtualMidi;
result = MIDIClientCreate(CFSTR("Virtual Client"),
                          MyMIDINotifyProc,
                          NULL,
                          &virtualMidi);

NSAssert( result == noErr, @"MIDIClientCreate failed. Error code: %d '%.4s'", (int) result, (const char *)&result);

// Create an endpoint
MIDIEndpointRef virtualEndpoint;
result = MIDIDestinationCreate(virtualMidi, @"Virtual Destination", MyMIDIReadProc, self.samplerUnit, &virtualEndpoint);

NSAssert( result == noErr, @"MIDIDestinationCreate failed. Error code: %d '%.4s'", (int) result, (const char *)&result);

MusicSequenceSetMIDIEndpoint(s, virtualEndpoint);

最佳答案

结束标记是一条Midi元消息,它永远不会发送到MIDI设备。它只是存在于MIDI文件中。

更新:

您可以使用用户事件在轨道循环时得到通知。

为用户事件添加回调:

static void sequenceUserCallback(void *inClientData,
                                 MusicSequence             inSequence,
                                 MusicTrack                inTrack,
                                 MusicTimeStamp            inEventTime,
                                 const MusicEventUserData *inEventData,
                                 MusicTimeStamp            inStartSliceBeat,
                                 MusicTimeStamp            inEndSliceBeat)
{
  NSLog(@"track was looped");
}

并创建一个用户事件,如下所示:
static MusicEventUserData userData = {1, 0x01 /* anything you want*/ };

MusicTrack musicTrack;
MusicSequenceGetIndTrack(sequence, 0 /* your track index of interest */, &musicTrack);

/* timestamp 0 should be fine if you always loop from the beginning;
   alternatively add the event at end of track */
MusicTrackNewUserEvent(musicTrack, 0 /* timestamp */ , &userData);

关于ios - 如何知道Midi回调中循环的结束,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23664825/

10-11 19:17
查看更多