ios - Get midi sequence (MusicSequence) markers generates with Logic -
i'm developing app play midi sequence (.mid) audio units. midi file created logic offers possibility add markers on timeline.
in code, use musicsequence musicplayer read file, , midiclientcreate mididestinationcreate parse midi packets.
the principal method
osstatus result = noerr; // initialise music sequence newmusicsequence(&_s); // string path of midi file // should located in resources folder nsstring *midifilepath = [[nsbundle mainbundle] pathforresource:@"mymidifile" oftype:@"mid"]; // create new url points midi file nsurl * midifileurl = [nsurl fileurlwithpath:midifilepath]; // load file musicsequencefileload(_s, (__bridge cfurlref) midifileurl, 0, 0); // initialise music player newmusicplayer(&_p); // load sound exs file [self loadfromexs:@"grand piano" withsampler:_samplerunit]; //load click [self loadfromsoundfont:@"hit set" withsampler:_samplerunit2]; //assign channel tracks musictrack track = null; musictrack track2 = null; musicsequencegetindtrack(_s, 1, &track); musicsequencegetindtrack(_s, 2, &track2); //assign tracks audio units musictracksetdestnode(track, _samplernode); musictracksetdestnode(track2, _samplernode2); // create client result = midiclientcreate(cfstr("virtual client"),mymidinotifyproc,(__bridge void *)(self),&_virtualmidi); nsassert( result == noerr, @"midiclientcreate failed. error code: %d '%.4s'", (int) result, (const char *)&result); // create endpoint result = mididestinationcreate(_virtualmidi, (cfstringref)@"virtual destination", mymidireadproc, (__bridge void *)(self), &_virtualendpoint); nsassert( result == noerr, @"mididestinationcreate failed. error code: %d '%.4s'", (int) result, (const char *)&result); // ************* set endpoint of sequence our virtual endpoint musicsequencesetmidiendpoint(_s, _virtualendpoint); // load sequence music player musicplayersetsequence(_p, _s); // called musicplayer setup. // reduces latency when musicplayerstart called musicplayerpreroll(_p); // starts music playing musicplayerstart(_p); and readproc function
void mymidireadproc(const midipacketlist *pktlist, audioprocessor *refcon, void *connrefcon) { audiounit *player = nil; midipacket *packet = (midipacket *)pktlist->packet; nsstring *messagetype; (int i=0; < pktlist->numpackets; i++) { byte midistatus = packet->data[0]; byte midicommand = midistatus >> 4;// mask off top 4 bits byte note = packet->data[1] & 0x7f; byte velocity = packet->data[2] & 0x7f; // find channel masking off low 4 bits nsinteger midichannel = midistatus & 0x0f; switch (midistatus & 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 << 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); } }
with readproc function, can see midi messages not markers...
if reopen midi file in logic, markers in file, where... how can in code ?
markers contained in midi file marker meta events. need extend parsing support meta events. meta events have status 0xff. markers next byte 0x06, length , number of characters.
Comments
Post a Comment