Question

I have a midi file looping (with MusicPlayer) and following callback procedure

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);
}
}

The NSLog(hex) will only show me packets beginning with 90 (note on), b0 (Controller), e0 (Pitch Bend) or c0 (Program Change). So do the callback functions not get the End Of Track Marker - FF 2F 00 - at all, or am i missing something here? I want to get notified every time the loop is starting over.

This is how i register the callback:

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);
Was it helpful?

Solution

The End Of Track Marker is a Midi Meta Message which is never send to MIDI devices; it just exists in MIDI files.

Updated:

You could use a user event to get notified when a track is looped.

Add a callback for the user event:

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

and create a user event like this:

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top