void ChangeInstrument(int instrument) { // Send a program change message on all four channels MusicDeviceMIDIEvent(synthUnit, kMidiMessageProgramChange + 0, instrument, 0, 0); MusicDeviceMIDIEvent(synthUnit, kMidiMessageProgramChange + 1, instrument, 0, 0); MusicDeviceMIDIEvent(synthUnit, kMidiMessageProgramChange + 2, instrument, 0, 0); MusicDeviceMIDIEvent(synthUnit, kMidiMessageProgramChange + 3, instrument, 0, 0); }
// ---------------------------------------------------------- void ofxAudioUnitSampler::setBank(const UInt32 MSB, const UInt32 LSB) // ---------------------------------------------------------- { MusicDeviceMIDIEvent(*_unit, kMidiMessage_ControlChange << 4 | midiChannelInUse, kMidiMessage_BankMSBControl, MSB, 0/*sample offset*/); MusicDeviceMIDIEvent(*_unit, kMidiMessage_ControlChange << 4 | midiChannelInUse, kMidiMessage_BankLSBControl, LSB, 0/*sample offset*/); }
static void MyMIDIReadProc(const MIDIPacketList *pktlist, void *refCon, void *connRefCon) { MyMIDIPlayer *player = (MyMIDIPlayer*) refCon; MIDIPacket *packet = (MIDIPacket *)pktlist->packet; for (int i=0; i < pktlist->numPackets; i++) { Byte midiStatus = packet->data[0]; Byte midiCommand = midiStatus >> 4; // is it a note-on or note-off if ((midiCommand == 0x09) || (midiCommand == 0x08)) { Byte note = packet->data[1] & 0x7F; Byte velocity = packet->data[2] & 0x7F; printf("midiCommand=%d. Note=%d, Velocity=%d\n", midiCommand, note, velocity); // send to augraph CheckError(MusicDeviceMIDIEvent (player->instrumentUnit, midiStatus, note, velocity, 0), "Couldn't send MIDI event"); } packet = MIDIPacketNext(packet); } }
void command(const MidiCommand* c) { OSStatus result; require_noerr(result = MusicDeviceMIDIEvent(synthUnit, c->command, c->byte1, c->byte2, 0), home); return; home: ; }
// ---------------------------------------------------------- void ofxAudioUnitSampler::setProgram(const UInt32 prog) // ---------------------------------------------------------- { MusicDeviceMIDIEvent(*_unit, kMidiMessage_ProgramChange << 4 | midiChannelInUse, prog, 0, 0/*sample offset*/); }
int setMidiInstrument (MidiDevice *midi, unsigned char channel, unsigned char instrument) { int result; if ((result = MusicDeviceMIDIEvent(midi->synth, 0xC0 | channel, instrument, 0, 0)) != noErr) logMessage(LOG_ERR, "Can't set MIDI instrument: %d", result); return result == noErr; }
// ---------------------------------------------------------- void ofxAudioUnitSampler::midiCC(const UInt32 controller, const UInt32 value) // ---------------------------------------------------------- { MusicDeviceMIDIEvent(*_unit, kMidiMessage_ControlChange << 4 | midiChannelInUse, controller, value, 0/*sample offset*/); }
void MidiDriver_CORE::send(uint32 b) { assert(isOpen()); byte status_byte = (b & 0x000000FF); byte first_byte = (b & 0x0000FF00) >> 8; byte second_byte = (b & 0x00FF0000) >> 16; MusicDeviceMIDIEvent(_synth, status_byte, first_byte, second_byte, 0); }
void AudioUnitHosting::ParseMIDI (const MIDIPacket &packet) { const Byte *p = packet.data, *pend = p + packet.length; while (p < pend) { Byte c = *p; if ((c & 0xE0) == 0xC0) { // 2-byte channel messages (program change 0xCn, mono pressure 0xDn) MusicDeviceMIDIEvent (mTargetUnit, *p, *(p + 1), 0, 0); p += 2; } else if ((signed char)c < (signed char)0xF0) { // 3 byte channel messages 0x80 - 0xEF (ex. above) // 0x8n - note off, 0x9n - note on, 0xAn - key pressure, 0xBn - control, 0xEn - pitch bend MusicDeviceMIDIEvent (mTargetUnit, *p, *(p + 1), *(p + 2), 0); p += 3; } else { // this just skips over any system MIDI messages ++p; } } }
// ---------------------------------------------------------- void ofxAudioUnitSampler::midiNoteOff(const UInt32 note, const UInt32 vel) // ---------------------------------------------------------- { UInt32 noteOffCommand = kMidiMessage_NoteOff << 4 | midiChannelInUse; MusicDeviceMIDIEvent( *_unit, noteOffCommand, note, vel, 0); }
// ---------------------------------------------------------- void ofxAudioUnitMidiReadProc(const MIDIPacketList *pktlist, void *readProcRefCon, void *srcConnRefCon) // ---------------------------------------------------------- { MIDIPacket * packet = (MIDIPacket *)pktlist->packet; AudioUnit unit = *(AudioUnit *)readProcRefCon; for(int i = 0; i < pktlist->numPackets; i++) { MusicDeviceMIDIEvent(unit, packet->data[0], packet->data[1], packet->data[2], 0); packet = MIDIPacketNext(packet); } }
int stopMidiNote (MidiDevice *midi, unsigned char channel) { int result; if ((result = MusicDeviceMIDIEvent(midi->synth, 0x90 | channel, midi->note, 0, 0)) != noErr) { logMessage(LOG_ERR, "Can't stop MIDI note: %d", result); return 0; } midi->note = 0; return 1; }
static DWORD MIDIOut_Reset(WORD wDevID) { unsigned chn; TRACE("%d\n", wDevID); if (wDevID >= MIDIOut_NumDevs) { WARN("bad device ID : %d\n", wDevID); return MMSYSERR_BADDEVICEID; } if (destinations[wDevID].caps.wTechnology == MOD_SYNTH) { for (chn = 0; chn < 16; chn++) { /* turn off every note */ MusicDeviceMIDIEvent(destinations[wDevID].synth, 0xB0 | chn, 0x7B, 0, 0); /* remove sustain on channel */ MusicDeviceMIDIEvent(destinations[wDevID].synth, 0xB0 | chn, 0x40, 0, 0); } } else FIXME("MOD_MIDIPORT\n"); /* FIXME: the LongData buffers must also be returned to the app */ return MMSYSERR_NOERROR; }
OSStatus MIDIEvent (UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame) { #if !TARGET_OS_WIN32 if (mMIDIEventProc != NULL) { return reinterpret_cast<MusicDeviceMIDIEventProc>(mMIDIEventProc) (mConnInstanceStorage, inStatus, inData1, inData2, inOffsetSampleFrame); } return MusicDeviceMIDIEvent (mUnit, inStatus, inData1, inData2, inOffsetSampleFrame); #else return paramErr; #endif }
static DWORD MIDIOut_Data(WORD wDevID, DWORD dwParam) { WORD evt = LOBYTE(LOWORD(dwParam)); UInt8 chn = (evt & 0x0F); TRACE("wDevID=%d dwParam=%08X\n", wDevID, dwParam); if (wDevID >= MIDIOut_NumDevs) { WARN("bad device ID : %d\n", wDevID); return MMSYSERR_BADDEVICEID; } if (destinations[wDevID].caps.wTechnology == MOD_SYNTH) { WORD d1 = HIBYTE(LOWORD(dwParam)); WORD d2 = LOBYTE(HIWORD(dwParam)); OSStatus err = noErr; err = MusicDeviceMIDIEvent(destinations[wDevID].synth, (evt & 0xF0) | chn, d1, d2, 0); if (err != noErr) { ERR("MusicDeviceMIDIEvent(%p, %04x, %04x, %04x, %d) return %s\n", destinations[wDevID].synth, (evt & 0xF0) | chn, d1, d2, 0, wine_dbgstr_fourcc(err)); return MMSYSERR_ERROR; } } else { UInt8 buffer[3]; buffer[0] = (evt & 0xF0) | chn; buffer[1] = HIBYTE(LOWORD(dwParam)); buffer[2] = LOBYTE(HIWORD(dwParam)); MIDIOut_Send(MIDIOutPort, destinations[wDevID].dest, buffer, 3); } return MMSYSERR_NOERROR; }
void start(int midiChannel, char const*const bankPath) { if (auGraph != 0) return; // don't multiply init midiChannelInUse = midiChannel; OSStatus result; //create the nodes of the graph AUNode synthNode; AudioComponentDescription cd; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; require_noerr (result = NewAUGraph (&auGraph), home); cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; require_noerr (result = AUGraphAddNode (auGraph, &cd, &synthNode), home); cd.componentType = kAudioUnitType_Effect; cd.componentSubType = kAudioUnitSubType_PeakLimiter; require_noerr (result = AUGraphAddNode (auGraph, &cd, &limiterNode), home); cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; require_noerr (result = AUGraphAddNode (auGraph, &cd, &outNode), home); require_noerr (result = AUGraphOpen (auGraph), home); require_noerr (result = AUGraphConnectNodeInput(auGraph, synthNode, 0, limiterNode, 0), home); require_noerr (result = AUGraphConnectNodeInput(auGraph, limiterNode, 0, outNode, 0), home); // ok we're good to go - get the Synth Unit... require_noerr (result = AUGraphNodeInfo(auGraph, synthNode, 0, &synthUnit), home); // if the user supplies a sound bank, we'll set that before we initialize and start playing if (bankPath) { // note: bankpath is a soundfont CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)bankPath, strlen(bankPath), false); if (url) { require_noerr (result = AudioUnitSetProperty(synthUnit, kMusicDeviceProperty_SoundBankURL, kAudioUnitScope_Global, 0, &url, sizeof(url) ), home); CFRelease(url); } } // ok we're set up to go - initialize and start the graph require_noerr (result = AUGraphInitialize (auGraph), home); //set our bank require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ControlChange << 4 | midiChannelInUse, kMidiMessage_BankMSBControl, 0, 0/*sample offset*/), home); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ProgramChange << 4 | midiChannelInUse, 0/*prog change num*/, 0, 0/*sample offset*/), home); CAShow(auGraph); // prints out the graph so we can see what it looks like... require_noerr (result = AUGraphStart(auGraph), home); return; home: shutdown(); }
// ---------------------------------------------------------- void ofxAudioUnitSampler::midiEvent(const UInt32 status, const UInt32 data1, const UInt32 data2) // ---------------------------------------------------------- { MusicDeviceMIDIEvent(*_unit, status, data1, data2, 0); }
OSStatus KeyboardHandler(EventHandlerCallRef next, EventRef event, void *data) { UInt32 kind; UInt32 keyCode; // Get the event kind kind = GetEventKind(event); // Switch on event kind switch (kind) { // Modifiers changed case kEventRawKeyModifiersChanged: return noErr; // Key down or key up case kEventRawKeyDown: // Get the key code GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(keyCode), NULL, &keyCode); switch (keyCode) { // Space bar case kKeyboardEscapeKey: case kKeyboardSpaceKey: // If the key isn't already down if (!bellows) { bellows = true; HIViewSetValue(spacebar, true); // Check the keys for (int i = 0; i < Length(buttons); i++) { for (int j = 0; j < Length(buttons[i]); j++) { // If a key is down if (buttons[i][j]) { // Stop the current note int k; switch (i) { case 0: k = (reverse)? Length(buttons[i]) - j - 2: j; break; case 1: k = (reverse)? Length(buttons[i]) - j - 1: j; break; case 2: k = (reverse)? Length(buttons[i]) - j - 1: j + 1; break; } int note = notes[type][k][!bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + i, note, 0, 0); // Play the new note note = notes[type][k][bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + i, note, volume, 0); } } } for (int i = 0; i < Length(bass); i++) { if (bass[i]) { // Play chord int k = (reverse)? Length(basskeys) - i - 1: i; int note = chords[key][k][!bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, volume, 0); note = chords[key][k][!bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, volume, 0); note = chords[key][k][bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + ROWS, note, volume, 0); note = chords[key][k][bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + ROWS, note, volume, 0); } } } break; // Check keyboard default: // Look up the key code in the keyboard table for (int i = 0; i < Length(keyboard); i++) { for (int j = 0; j < Length(keyboard[i]); j++) { if (keyboard[i][j] == keyCode && !buttons[i][j]) { buttons[i][j] = true; // Play the note int k; switch (i) { case 0: k = (reverse)? Length(buttons[i]) - j - 2: j; break; case 1: k = (reverse)? Length(buttons[i]) - j - 1: j; break; case 2: k = (reverse)? Length(buttons[i]) - j - 1: j + 1; break; } if ((type == CHROMATIC) && (hilites[key][i][k] == true)) HIViewSetValue(display[i][j], false); else HIViewSetValue(display[i][j], true); int note = notes[type][k][bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + i, note, volume, 0); return noErr; } } } for (int i = 0; i < Length(basskeys); i++) { if (((basskeys[i][0] == keyCode) || (basskeys[i][1] == keyCode)) && !bass[i]) { bass[i] = true; HIViewSetValue(bassdisplay[i], true); int k = (reverse)? Length(basskeys) - i - 1: i; int note = chords[key][k][bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + ROWS, note, volume, 0); note = chords[key][k][bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + ROWS, note, volume, 0); } } break; } break; case kEventRawKeyUp: // Get the key code GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(keyCode), NULL, &keyCode); switch (keyCode) { // Space bar case kKeyboardEscapeKey: case kKeyboardSpaceKey: // If the key isn't already up if (bellows) { bellows = false; HIViewSetValue(spacebar, false); // Check the keys for (int i = 0; i < Length(buttons); i++) { for (int j = 0; j < Length(buttons[i]); j++) { // If a key is down if (buttons[i][j]) { // Stop the current note int k; switch (i) { case 0: k = (reverse)? Length(buttons[i]) - j - 2: j; break; case 1: k = (reverse)? Length(buttons[i]) - j - 1: j; break; case 2: k = (reverse)? Length(buttons[i]) - j - 1: j + 1; break; } int note = notes[type][k][!bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + i, note, 0, 0); // Play the new note note = notes[type][k][bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + i, note, volume, 0); } } } for (int i = 0; i < Length(bass); i++) { if (bass[i]) { // Play chord int k = (reverse)? Length(basskeys) - i - 1: i; int note = chords[key][k][!bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, volume, 0); note = chords[key][k][!bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, volume, 0); note = chords[key][k][bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + ROWS, note, volume, 0); note = chords[key][k][bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOn + ROWS, note, volume, 0); } } } break; // Check keyboard default: // Look up the key code in the keyboard table for (int i = 0; i < Length(keyboard); i++) { for (int j = 0; j < Length(keyboard[i]); j++) { if (keyboard[i][j] == keyCode && buttons[i][j]) { buttons[i][j] = false; // Stop note int k; switch (i) { case 0: k = (reverse)? Length(buttons[i]) - j - 2: j; break; case 1: k = (reverse)? Length(buttons[i]) - j - 1: j; break; case 2: k = (reverse)? Length(buttons[i]) - j - 1: j + 1; break; } if ((type == CHROMATIC) && (hilites[key][i][k] == true)) HIViewSetValue(display[i][j], true); else HIViewSetValue(display[i][j], false); int note = notes[type][k][bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + i, note, 0, 0); return noErr; } } } for (int i = 0; i < Length(basskeys); i++) { if (((basskeys[i][0] == keyCode) || (basskeys[i][1] == keyCode)) && bass[i]) { bass[i] = false; HIViewSetValue(bassdisplay[i], false); int k = (reverse)? Length(basskeys) - i - 1: i; int note = chords[key][k][bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, volume, 0); note = chords[key][k][bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, volume, 0); } } break; } break; default: return eventNotHandledErr; } // Report success return noErr; }
OSStatus ApplicationHandler(EventHandlerCallRef next, EventRef event, void *data) { ProcessSerialNumber them; ProcessSerialNumber us; Boolean same; UInt32 kind; // Get event kind kind = GetEventKind(event); // switch on event kind switch (kind) { // Front app switched case kEventAppFrontSwitched: // Get their process id GetEventParameter(event, kEventParamProcessID, typeProcessSerialNumber, NULL, sizeof(them), NULL, &them); // Get our process id GetCurrentProcess(&us); // Is it the same? SameProcess(&them, &us, &same); // If not the same if (!same) { // Turn all the notes off and reset all the buttons that // are down for (int i = 0; i < Length(bass); i++) { // Bass buttons if (bass[i]) { bass[i] = false; HIViewSetValue(bassdisplay[i], false); int k = (reverse)? Length(basskeys) - i - 1: i; int note = chords[key][k][bellows][0]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, 0, 0); note = chords[key][k][bellows][1]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + ROWS, note, 0, 0); } } for (int i = 0; i < Length(buttons); i++) { for (int j = 0; j < Length(buttons[i]); j++) { // Melody buttons if (buttons[i][j]) { buttons[i][j] = false; int k; switch (i) { case 0: k = (reverse)? Length(buttons[i]) - j - 2: j; break; case 1: k = (reverse)? Length(buttons[i]) - j - 1: j; break; case 2: k = (reverse)? Length(buttons[i]) - j - 1: j + 1; break; } if ((type == CHROMATIC) && (hilites[key][i][j] == true)) HIViewSetValue(display[i][k], true); else HIViewSetValue(display[i][k], false); int note = notes[type][k][bellows] + keyvals[key][i]; MusicDeviceMIDIEvent(synthUnit, kMidiMessageNoteOff + i, note, 0, 0); } } } if (bellows) { // Space bar button bellows = false; HIViewSetValue(spacebar, false); } } break; default: return eventNotHandledErr; } // Return ok return noErr; }
void auLoader::processMidi(int type, int byte1, int byte2, long frames) { if(m_desc.componentType == kAudioUnitType_MusicDevice || m_desc.componentType == kAudioUnitType_MusicEffect) { MusicDeviceMIDIEvent(m_plugin, type, byte1, byte2, frames); } }
int main(int argc, char *argv[]) { AUGraph audioGraph; NewAUGraph(&audioGraph); AudioComponentDescription cd; AUNode outputNode; AudioUnit outputUnit; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; cd.componentType = kAudioUnitType_Output; cd.componentSubType = kAudioUnitSubType_DefaultOutput; AUGraphAddNode(audioGraph, &cd, &outputNode); AUGraphNodeInfo(audioGraph, outputNode, &cd, &outputUnit); AUNode mixerNode; AudioUnit mixerUnit; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; cd.componentType = kAudioUnitType_Mixer; cd.componentSubType = kAudioUnitSubType_StereoMixer; AUGraphAddNode(audioGraph, &cd, &mixerNode); AUGraphNodeInfo(audioGraph, mixerNode, &cd, &mixerUnit); AUGraphConnectNodeInput(audioGraph, mixerNode, 0, outputNode, 0); AUGraphOpen(audioGraph); AUGraphInitialize(audioGraph); AUGraphStart(audioGraph); AUNode synthNode; AudioUnit synthUnit; cd.componentManufacturer = kAudioUnitManufacturer_Apple; cd.componentFlags = 0; cd.componentFlagsMask = 0; cd.componentType = kAudioUnitType_MusicDevice; cd.componentSubType = kAudioUnitSubType_DLSSynth; AUGraphAddNode(audioGraph, &cd, &synthNode); AUGraphNodeInfo(audioGraph, synthNode, &cd, &synthUnit); AUGraphConnectNodeInput(audioGraph, synthNode, 0, mixerNode, 0); AUGraphUpdate(audioGraph, NULL); CAShow(audioGraph); MusicDeviceMIDIEvent(synthUnit, 0x90, 60, 127, 0); sleep(1); MusicDeviceMIDIEvent(synthUnit, 0x90, 62, 127, 0); sleep(1); MusicDeviceMIDIEvent(synthUnit, 0x90, 64, 127, 0); sleep(1); sleep(5); return(0); }
int main (int argc, const char * argv[]) { AUGraph graph = 0; AudioUnit synthUnit; OSStatus result; char* bankPath = 0; UInt8 midiChannelInUse = 0; //we're using midi channel 1... // this is the only option to main that we have... // just the full path of the sample bank... // On OS X there are known places were sample banks can be stored // Library/Audio/Sounds/Banks - so you could scan this directory and give the user options // about which sample bank to use... if (argc > 1) bankPath = const_cast<char*>(argv[1]); require_noerr (result = CreateAUGraph (graph, synthUnit), home); // if the user supplies a sound bank, we'll set that before we initialize and start playing if (bankPath) { FSSpec soundBankSpec; require_noerr (result = PathToFSSpec (bankPath, soundBankSpec), home); printf ("Setting Sound Bank:%s\n", bankPath); require_noerr (result = AudioUnitSetProperty (synthUnit, kMusicDeviceProperty_SoundBankFSSpec, kAudioUnitScope_Global, 0, &soundBankSpec, sizeof(soundBankSpec)), home); } // ok we're set up to go - initialize and start the graph require_noerr (result = AUGraphInitialize (graph), home); //set our bank require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ControlChange << 4 | midiChannelInUse, kMidiMessage_BankMSBControl, 0, 0/*sample offset*/), home); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, kMidiMessage_ProgramChange << 4 | midiChannelInUse, 0/*prog change num*/, 0, 0/*sample offset*/), home); CAShow (graph); // prints out the graph so we can see what it looks like... require_noerr (result = AUGraphStart (graph), home); // we're going to play an octave of MIDI notes: one a second for (int i = 0; i < 13; i++) { UInt32 noteNum = i + 60; UInt32 onVelocity = 127; UInt32 noteOnCommand = kMidiMessage_NoteOn << 4 | midiChannelInUse; printf ("Playing Note: Status: 0x%lX, Note: %ld, Vel: %ld\n", noteOnCommand, noteNum, onVelocity); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, noteNum, onVelocity, 0), home); // sleep for a second usleep (1 * 1000 * 1000); require_noerr (result = MusicDeviceMIDIEvent(synthUnit, noteOnCommand, noteNum, 0, 0), home); } // ok we're done now home: if (graph) { AUGraphStop (graph); // stop playback - AUGraphDispose will do that for us but just showing you what to do DisposeAUGraph (graph); } return result; }