Index: SC_PortMIDI.cpp =================================================================== --- SC_PortMIDI.cpp (revision 8648) +++ SC_PortMIDI.cpp (working copy) @@ -46,6 +46,7 @@ #include "PyrSched.h" #include "GC.h" #include + // symbols to call back into lang PyrSymbol* s_domidiaction; PyrSymbol* s_midiNoteOnAction; @@ -67,6 +68,7 @@ bool gMIDIInitialized = false; PmStream* gMidiInStreams[kMaxMidiPorts]; +PmStream* gMidiOutStreams[kMaxMidiPorts]; std::map gMidiInputIndexToPmDevIndex; std::map gMidiOutputIndexToPmDevIndex; std::map gMidiPmDevIndexToInputIndex; @@ -83,19 +85,16 @@ /* if INPUT_BUFFER_SIZE is 0, PortMidi uses a default value */ #define PMSTREAM_INPUT_BUFFER_SIZE 0 - #define PMSTREAM_OUTPUT_BUFFER_SIZE 100 #define PMSTREAM_DRIVER_INFO NULL #define PMSTREAM_TIME_PROC NULL #define PMSTREAM_TIME_INFO NULL + /* use zero latency because we want output to be immediate */ #define LATENCY 0 - extern bool compiledOK; -void midiCleanUp(); - inline void TPmErr(PmError err) { if( err != pmNoError) throw err; @@ -107,38 +106,7 @@ ScopeMutexLock mulo(&gPmStreamMutex); PmError result; PmEvent buffer; /* just one message at a time */ -// long msg; - /* - // check for messages - do { - result = Pm_Dequeue(main_to_midi, &msg); - if (result) - { - if (msg >= -127 && msg <= 127) - transpose = msg; - else if (msg == QUIT_MSG) - { - // acknowledge receipt of quit message - Pm_Enqueue(midi_to_main, &msg); - active = FALSE; - return; - } - else if (msg == MONITOR_MSG) - { - // main has requested a pitch. monitor is a flag that - // records the request: - monitor = TRUE; - } - else if (msg == THRU_MSG) - { - // toggle Thru on or off - midi_thru = !midi_thru; - } - } - } while (result); - */ - for( int i = 0 ; i < kMaxMidiPorts; ++i ) { int pmdid = gMidiInputIndexToPmDevIndex[i]; @@ -154,6 +122,7 @@ if (Pm_Read(midi_in, &buffer, 1) == pmBufferOverflow) continue; // unless there was overflow, we should have a message now + Tstatus = Pm_MessageStatus(buffer.message); data1 = Pm_MessageData1(buffer.message); data2 = Pm_MessageData2(buffer.message); @@ -173,7 +142,7 @@ ++g->sp; SetObject(g->sp, s_midiin->u.classobj); // Set the class MIDIIn //set arguments: - ++g->sp;SetInt(g->sp, pmdid); //src + ++g->sp; SetInt(g->sp, pmdid); //src // ++g->sp; SetInt(g->sp, status); //status ++g->sp; SetInt(g->sp, chan); //chan @@ -221,7 +190,7 @@ break; */ } - g->canCallOS = false; + g->canCallOS = true; } pthread_mutex_unlock (&gLangMutex); } @@ -229,9 +198,11 @@ } // if (midi_in) } // for loop until kMaxMidiPorts } + /* ------------------------------------------------------------- */ +void midiCleanUp(); int initMIDI(int numIn, int numOut) { try { @@ -245,6 +216,8 @@ int nbDev = Pm_CountDevices(); int inIndex = 0; int outIndex = 0; + int pmdid; + for( int i = 0; i < nbDev ; ++i ) { const PmDeviceInfo* devInfo = Pm_GetDeviceInfo(i); if( devInfo->input ) @@ -255,15 +228,22 @@ } if( devInfo->output ) { - gNumMIDIInPorts++; + gNumMIDIOutPorts++; gMidiOutputIndexToPmDevIndex[outIndex++] = i; gMidiPmDevIndexToOutputIndex[i] = outIndex; } } + + for( int i = 0; i < gNumMIDIOutPorts; i++) { + pmdid = gMidiOutputIndexToPmDevIndex[i]; + Pm_OpenOutput(&gMidiOutStreams[i], pmdid, NULL, 512, NULL, NULL, 0); + } } catch(PmError) { return errFailed; } + + gMIDIInitialized = true; return errNone; } /* @@ -272,29 +252,32 @@ void midiCleanUp() { ScopeMutexLock mulo(&gPmStreamMutex); - for (int i=0; isp - 1; PyrSlot *c = g->sp; @@ -448,10 +434,11 @@ return err; PmError pmerr = Pm_Close(gMidiInStreams[uid]); - gMidiInStreams[uid] = NULL; + if(pmerr != pmNoError) return errFailed; + gMidiInStreams[uid] = NULL; return errNone; } @@ -480,26 +467,18 @@ */ int prDisposeMIDIClient(VMGlobals *g, int numArgsPushed) { - /* - PyrSlot *a; - a = g->sp - 1; - OSStatus err = MIDIClientDispose(gMIDIClient); - if (err) { - post("error could not dispose MIDIClient \n"); - return errFailed; - } - return errNone; - */ - return errFailed; + midiCleanUp(); + return errNone; } /* ------------------------------------------------------------- */ int prRestartMIDI(VMGlobals *g, int numArgsPushed) { -// MIDIRestart(); -// return errNone; - return errFailed; + midiCleanUp(); + //initMIDI(); + return errNone; + } /* @@ -558,34 +537,12 @@ */ return errFailed; } - /* ------------------------------------------------------------- */ -/* -void sendmidi(int port, MIDIEndpointRef dest, int length, int hiStatus, int loStatus, int aval, int bval, float late) -{ - MIDIPacketList mpktlist; - MIDIPacketList * pktlist = &mpktlist; - MIDIPacket * pk = MIDIPacketListInit(pktlist); - //lets add some latency - float latency = 1000000 * late ; //ms to nano - UInt64 utime = AudioConvertNanosToHostTime( AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) + (UInt64)latency); - ByteCount nData = (ByteCount) length; - pk->data[0] = (Byte) (hiStatus & 0xF0) | (loStatus & 0x0F); - pk->data[1] = (Byte) aval; - pk->data[2] = (Byte) bval; - pk = MIDIPacketListAdd(pktlist, sizeof(struct MIDIPacketList) , pk,(MIDITimeStamp) utime,nData,pk->data); - //OSStatus error = - MIDISend(gMIDIOutPort[port], dest, pktlist ); -} -*/ -/* -------------------------------------------------------------- -*/ int prSendMIDIOut(struct VMGlobals *g, int numArgsPushed) { -/* + ScopeMutexLock mulo(&gPmStreamMutex); //port, uid, len, hiStatus, loStatus, a, b, latency //PyrSlot *m = g->sp - 8; PyrSlot *p = g->sp - 7; @@ -600,12 +557,11 @@ PyrSlot *b = g->sp - 1; PyrSlot *plat = g->sp; - int err, outputIndex, uid, length, hiStatus, loStatus, aval, bval; float late; err = slotIntVal(p, &outputIndex); if (err) return err; - if (outputIndex < 0 || outputIndex >= gNumMIDIInPorts) return errIndexOutOfRange; + if (outputIndex < 0 || outputIndex >= gNumMIDIOutPorts) return errIndexOutOfRange; err = slotIntVal(u, &uid); if (err) return err; @@ -622,17 +578,10 @@ err = slotFloatVal(plat, &late); if (err) return err; - MIDIEndpointRef dest; - MIDIObjectType mtype; - MIDIObjectFindByUniqueID(uid, (MIDIObjectRef*)&dest, &mtype); - if (mtype != kMIDIObjectType_Destination) return errFailed; + Pm_WriteShort(gMidiOutStreams[uid], 0, + Pm_Message((hiStatus & 0xF0) | (loStatus & 0x0F) , aval, bval)); - if (!dest) return errFailed; - - sendmidi(outputIndex, dest, length, hiStatus, loStatus, aval, bval, late); return errNone; - */ - return errFailed; } // not needed in PortMIDI: