title: Get midi sequence (MusicSequence) markers generates with Logic
body: <p>I'm developing an app which play a midi sequence (.mid) with audio units.
  The midi file is created with Logic which offers the possibility to add markers on the timeline.</p>
  
  <p>In the code, I use MusicSequence MusicPlayer to read the file, and MIDIClientCreate MIDIDestinationCreate to parse MIDI packets.</p>
  
  <p><strong>The principal method</strong></p>
  
  <pre><code>    OSStatus result = noErr;
  
  
  // Initialise the music sequence
  NewMusicSequence(&amp;_s);
  
  // Get a string to the path of the MIDI file which
  // should be located in the Resources folder
  NSString *midiFilePath = [[NSBundle mainBundle]
                            pathForResource:@"mymidifile"
                            ofType:@"mid"];
  
  // Create a new URL which points to the MIDI file
  NSURL * midiFileURL = [NSURL fileURLWithPath:midiFilePath];
  
  // Load the file
  MusicSequenceFileLoad(_s, (__bridge CFURLRef) midiFileURL, 0, 0);
  
  
  
  // Initialise the music player
  NewMusicPlayer(&amp;_p);
  
  
  // Load the sound from EXS file
  [self loadFromEXS:@"Grand Piano" withSampler:_samplerUnit];
  
  //Load Click
  [self loadFromSoundFont:@"hit set" withSampler:_samplerUnit2];
  
  
  //Assign channel to tracks
  MusicTrack track = NULL;
  MusicTrack track2 = NULL;
  MusicSequenceGetIndTrack(_s, 1, &amp;track);
  MusicSequenceGetIndTrack(_s, 2, &amp;track2);
  
  //Assign tracks to audio units
  MusicTrackSetDestNode(track, _samplerNode);
  MusicTrackSetDestNode(track2, _samplerNode2);
  
  
  // Create a client
  result = MIDIClientCreate(CFSTR("Virtual Client"),MyMIDINotifyProc,(__bridge void *)(self),&amp;_virtualMidi);
  NSAssert( result == noErr, @"MIDIClientCreate failed. Error code: %d '%.4s'", (int) result, (const char *)&amp;result);
  
  
  // Create an endpoint
  result = MIDIDestinationCreate(_virtualMidi, (CFStringRef)@"Virtual Destination", MyMIDIReadProc, (__bridge void *)(self), &amp;_virtualEndPoint);
  
  NSAssert( result == noErr, @"MIDIDestinationCreate failed. Error code: %d '%.4s'", (int) result, (const char *)&amp;result);
  
  
  // ************* Set the endpoint of the sequence to be our virtual endpoint
  MusicSequenceSetMIDIEndpoint(_s, _virtualEndPoint);
  
  
  
  
  // Load the sequence into the music player
  MusicPlayerSetSequence(_p, _s);
  // Called to do some MusicPlayer setup. This just
  // reduces latency when MusicPlayerStart is called
  MusicPlayerPreroll(_p);
  // Starts the music playing
  MusicPlayerStart(_p);
  </code></pre>
  
  <p><strong>And my readProc function</strong></p>
  
  <pre><code>void MyMIDIReadProc(const MIDIPacketList *pktlist,
                  AudioProcessor *refCon,
                  void *connRefCon) {
  
  
  AudioUnit *player = nil;
  
  MIDIPacket *packet = (MIDIPacket *)pktlist-&gt;packet;
  NSString *messageType;
  
  for (int i=0; i &lt; pktlist-&gt;numPackets; i++) {
  
  
      Byte midiStatus = packet-&gt;data[0];
      Byte midiCommand = midiStatus &gt;&gt; 4;// mask off all but top 4 bits
      Byte note = packet-&gt;data[1] &amp; 0x7F;
      Byte velocity = packet-&gt;data[2] &amp; 0x7F;
  
      // find the channel by masking off all but the low 4 bits
      NSInteger midiChannel = midiStatus &amp; 0x0F;
  
  
      switch (midiStatus &amp; 0xF0) {
          case 0x80:
              messageType = @"Note Off";
              break;
  
          case 0x90:
              messageType = @"Note On";
              break;
  
          case 0xA0:
              messageType = @"Aftertouch";
              break;
  
          case 0xB0:
              messageType = @"Control change";
              break;
  
          case 0xC0:
              messageType = @"Program Change";
              break;
  
          case 0xD0:
              messageType = @"Channel Pressure";
              break;
  
          case 0xE0:
              messageType = @"Pitch Wheel";
              break;
  
          default:
              messageType = @"Unk";
              break;
      }
      NSLog(@"%@",messageType);
      int noteNumber = ((int) note) % 12;
      NSString *noteType;
      switch (noteNumber) {
          case 0:
              noteType = @"C";
              break;
          case 1:
              noteType = @"C#/Db";
              break;
          case 2:
              noteType = @"D";
              break;
          case 3:
              noteType = @"D#/Eb";
              break;
          case 4:
              noteType = @"E";
              break;
          case 5:
              noteType = @"F";
              break;
          case 6:
              noteType = @"F#/Gb";
              break;
          case 7:
              noteType = @"G";
              break;
          case 8:
              noteType = @"G#/Ab";
              break;
          case 9:
              noteType = @"A";
              break;
          case 10:
              noteType = @"A#/Bb";
              break;
          case 11:
              noteType = @"B";
              break;
          default:
              break;
      }
  
  
  
  
      if( velocity == 0 ){
  
          UInt32 noteOff =    kMIDIMessage_NoteOff &lt;&lt; 4 | 0;
          if( midiChannel == 0 ){
              MusicDeviceMIDIEvent (refCon.samplerUnit, noteOff, note, 0, 0);
          }else if( midiChannel == 1 ){
              MusicDeviceMIDIEvent (refCon.samplerUnit2, noteOff, note, 0, 0);
          }
  
      }else{
  
          if( midiChannel == 0 ){
              MusicDeviceMIDIEvent (refCon.samplerUnit, midiStatus, note, velocity, 0);
          }else if( midiChannel == 1 ){
              MusicDeviceMIDIEvent (refCon.samplerUnit2, midiStatus, note, velocity, 0);
          }
  
      }
  
      packet = MIDIPacketNext(packet);
  }
  </code></pre>
  
  <p>}</p>
  
  <p>With my readProc function, I can see all midi messages but not the markers...</p>
  
  <p>If I reopen the midi file in Logic, the markers are in file, but where... How can I get it in the code ?</p>