Here's a minimalistic answer to the question that I've learned and made work meanwhile. It's a matter of making a midiReadProc generate values which an audioRenderProc can accept as parameters. Please note that this works in stand-alone apps. For writing AU-plug-ins I recommend understanding and using CoreAudioUtilityClasses, as provided by Apple.
A simplest example of createMidi in C:
//these have to be declared somewhere
MIDIClientRef midiclient;
MIDIPortRef midiin;
void createMIDI (void)
{
//create MIDI input and client - - - - - - - - - - -
midiclient = 0;
CheckError(MIDIClientCreate(CFSTR("MIDI_Client"),
NULL,
/*midiClientNotifyRefCon*/NULL,
&midiclient),
"MIDI Client Create Error\n");
CheckError(MIDIInputPortCreate(midiclient,
CFSTR("MIDI_Input"),
midiReadProc,
NULL,
&midiin),
"MIDI Port Create Error\n");
//connect MIDI - - - - - - - - - - - - - - - - - - -
ItemCount mSrcs = MIDIGetNumberOfSources();
printf("MIDI Sources: %ld\n", (long)mSrcs);
ItemCount iSrc;
for (iSrc=0; iSrc<mSrcs; iSrc++) {
MIDIEndpointRef src = MIDIGetSource(iSrc);
MIDIPortConnectSource(midiin, src, NULL);
}
}
CheckError( ) is a generic utility function modeled after "Learning Core Audio", by C.Adamson & K.Avila, ISBN 0-321-63684-8...
...and a plain-C midiReadProc template. Please note that many manufacturers of MIDI hardware don't implement the standardized noteOff event, but rather a "hacked" version consisting of a zero-velocity-noteOn, due to alleged improving MIDI-latency issues, but they hardly document it. So, one has to check against both scenarios:
void midiReadProc(const MIDIPacketList *packetList,
void* readProcRefCon,
void* srcConnRefCon)
{
Byte note;
Byte velocity;
MIDIPacket *packet = (MIDIPacket*)packetList->packet;
int count = packetList->numPackets;
for (int k=0; k < count; k++) {
Byte midiStatus = packet->data[0];
Byte midiChannel = midiStatus & 0x0F;
Byte midiCommand = midiStatus >> 4;
if ((midiCommand == 0x08)||(midiCommand == 0x09)){
if(midiCommand == 0x09){
note = packet->data[1] & 0x7F;
velocity = packet->data[2] & 0x7F;
if (velocity == 0x0){ //"hacked" note-off
; //do something
}else{//note on
; //do something
}
}
if(midiCommand == 0x08){ //proper note-off
;//do something
}
}else{
;//do something else
}
packet = MIDIPacketNext(packet);
}//end for (k = 0; ...;...)
}
Everything else is a matter of common good programing practice.