diff --git a/build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp b/build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp index fb557897af..e151bd025b 100644 --- a/build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp +++ b/build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp @@ -573,8 +573,6 @@ MidiInput::~MidiInput() OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint)); OK (MIDIPortDispose (mpe->port)); delete mpe; - - activeCallbacks.minimiseStorageOverheads(); } void MidiInput::start() diff --git a/build/win32/platform_specific_code/juce_win32_Midi.cpp b/build/win32/platform_specific_code/juce_win32_Midi.cpp index 3b0c2ed90e..9f004d1b61 100644 --- a/build/win32/platform_specific_code/juce_win32_Midi.cpp +++ b/build/win32/platform_specific_code/juce_win32_Midi.cpp @@ -47,7 +47,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== static const int midiBufferSize = 1024 * 10; static const int numInHeaders = 32; -static const int inBufferSize = 128; +static const int inBufferSize = 256; class MidiInThread : public Thread { @@ -89,7 +89,7 @@ public: } //============================================================================== - void handle (const uint32 message, const uint32 timeStamp) + void handle (const uint32 message, const uint32 timeStamp) throw() { jassert (validityInt == 0x12345678); if (validityInt != 0x12345678) @@ -99,17 +99,7 @@ public: if (byte < 0x80) return; - static const char extraDataLengths[] = { - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - const int numBytes = extraDataLengths [byte - 0x80] + 1; + const int numBytes = MidiMessage::getMessageLengthFromFirstByte ((uint8) byte); const double time = timeStampToTime (timeStamp); @@ -131,7 +121,7 @@ public: notify(); } - void handleSysEx (MIDIHDR* hdr, const uint32 timeStamp) + void handleSysEx (MIDIHDR* const hdr, const uint32 timeStamp) throw() { jassert (validityInt == 0x12345678); if (validityInt != 0x12345678) @@ -163,7 +153,7 @@ public: } } - void writeBlock (int i) + void writeBlock (const int i) throw() { hdr[i].dwBytesRecorded = 0; MMRESULT res = midiInPrepareHeader (hIn, &hdr[i], sizeof (MIDIHDR)); @@ -226,7 +216,7 @@ public: } } - void start() + void start() throw() { jassert (hIn != 0); if (hIn != 0 && ! isStarted) @@ -253,7 +243,7 @@ public: } } - void stop() + void stop() throw() { if (isStarted) { @@ -297,7 +287,7 @@ private: int pendingLength; char pending [midiBufferSize]; - double timeStampToTime (uint32 timeStamp) + double timeStampToTime (uint32 timeStamp) throw() { timeStamp += startTime; @@ -357,13 +347,14 @@ int MidiInput::getDefaultDeviceIndex() return 0; } -MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) +MidiInput* MidiInput::openDevice (const int index, MidiInputCallback* const callback) { if (callback == 0) return 0; UINT deviceId = MIDI_MAPPER; int n = 0; + String name; const int num = midiInGetNumDevs(); @@ -377,6 +368,7 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) if (index == n) { deviceId = i; + name = String (mc.szPname, sizeof (mc.szPname)); break; } @@ -384,7 +376,7 @@ MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback) } } - MidiInput* const in = new MidiInput (getDevices() [index]); + MidiInput* const in = new MidiInput (name); MidiInThread* const thread = new MidiInThread (in, callback); HMIDIIN h; @@ -424,12 +416,12 @@ MidiInput::~MidiInput() void MidiInput::start() { - ((MidiInThread*)internal)->start(); + ((MidiInThread*) internal)->start(); } void MidiInput::stop() { - ((MidiInThread*)internal)->stop(); + ((MidiInThread*) internal)->stop(); } @@ -515,41 +507,43 @@ MidiOutput* MidiOutput::openDevice (int index) for (i = handles.size(); --i >= 0;) { - MidiOutHandle* const han = (MidiOutHandle*) handles[i]; + MidiOutHandle* const han = (MidiOutHandle*) handles.getUnchecked(i); if (han != 0 && han->deviceId == deviceId) { han->refCount++; - MidiOutput* out = new MidiOutput(); - out->internal = (void*)han; + + MidiOutput* const out = new MidiOutput(); + out->internal = (void*) han; return out; } } - HMIDIOUT h = 0; - MMRESULT res = MMSYSERR_NOERROR + 1; - for (i = 4; --i >= 0;) { - UINT devId = deviceId; // copy because this call changes the value - res = midiOutOpen (&h, devId, 0, 0, CALLBACK_NULL); - if (res != MMSYSERR_ALLOCATED) - break; + HMIDIOUT h = 0; + MMRESULT res = midiOutOpen (&h, deviceId, 0, 0, CALLBACK_NULL); - Sleep (100); - } - - if (res == MMSYSERR_NOERROR) - { - MidiOutHandle* const han = new MidiOutHandle(); - han->deviceId = deviceId; - han->refCount = 1; - han->handle = h; - handles.add (han); - - MidiOutput* const out = new MidiOutput(); - out->internal = (void*)han; - return out; + if (res == MMSYSERR_NOERROR) + { + MidiOutHandle* const han = new MidiOutHandle(); + han->deviceId = deviceId; + han->refCount = 1; + han->handle = h; + handles.add (han); + + MidiOutput* const out = new MidiOutput(); + out->internal = (void*) han; + return out; + } + else if (res == MMSYSERR_ALLOCATED) + { + Sleep (100); + } + else + { + break; + } } return 0; @@ -566,8 +560,7 @@ MidiOutput::~MidiOutput() if (handles.contains ((void*) h) && --(h->refCount) == 0) { midiOutClose (h->handle); - handles.removeValue ((void*)h); - handles.minimiseStorageOverheads(); + handles.removeValue ((void*) h); delete h; } } @@ -601,10 +594,10 @@ bool MidiOutput::getVolume (float& leftVol, void MidiOutput::setVolume (float leftVol, float rightVol) { - const MidiOutHandle* const handle = (MidiOutHandle*)internal; + const MidiOutHandle* const handle = (MidiOutHandle*) internal; DWORD n; - unsigned short* nn = (unsigned short*) &n; + unsigned short* const nn = (unsigned short*) &n; nn[0] = (unsigned short) jlimit (0, 0xffff, (int)(rightVol * 0xffff)); nn[1] = (unsigned short) jlimit (0, 0xffff, (int)(leftVol * 0xffff)); midiOutSetVolume (handle->handle, n); diff --git a/src/juce_appframework/audio/midi/juce_MidiBuffer.cpp b/src/juce_appframework/audio/midi/juce_MidiBuffer.cpp index 44e8c955df..93cb664c8a 100644 --- a/src/juce_appframework/audio/midi/juce_MidiBuffer.cpp +++ b/src/juce_appframework/audio/midi/juce_MidiBuffer.cpp @@ -117,17 +117,7 @@ static int findActualEventLength (const uint8* const data, } else if (byte >= 0x80) { - static const char messageLengths[] = { - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - - size = jmin (maxBytes, messageLengths [byte - 0x80]); + size = jmin (maxBytes, MidiMessage::getMessageLengthFromFirstByte ((uint8) byte)); } return size; diff --git a/src/juce_appframework/audio/midi/juce_MidiMessage.cpp b/src/juce_appframework/audio/midi/juce_MidiMessage.cpp index 5919e115a3..a6c1d32a7b 100644 --- a/src/juce_appframework/audio/midi/juce_MidiMessage.cpp +++ b/src/juce_appframework/audio/midi/juce_MidiMessage.cpp @@ -59,6 +59,29 @@ int MidiMessage::readVariableLengthVal (const uint8* data, return v; } +int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) throw() +{ + // this method only works for valid starting bytes of a short midi message + jassert (firstByte >= 0x80 + && firstByte != 0xff + && firstByte != 0xf0 + && firstByte != 0xf7); + + static const char messageLengths[] = + { + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + + return messageLengths [firstByte & 0x7f]; +} + //============================================================================== MidiMessage::MidiMessage (const uint8* const d, const int dataSize, @@ -67,12 +90,17 @@ MidiMessage::MidiMessage (const uint8* const d, message (0), size (dataSize) { + jassert (dataSize > 0); + if (dataSize <= 4) data = (uint8*) &message; else data = (uint8*) juce_malloc (dataSize); memcpy (data, d, dataSize); + + // check that the length matches the data.. + jassert (size > 3 || getMessageLengthFromFirstByte (*d) == size); } MidiMessage::MidiMessage (const int byte1, @@ -82,6 +110,9 @@ MidiMessage::MidiMessage (const int byte1, size (1) { data[0] = (uint8) byte1; + + // check that the length matches the data.. + jassert (getMessageLengthFromFirstByte ((uint8) byte1) == 1); } MidiMessage::MidiMessage (const int byte1, @@ -93,6 +124,9 @@ MidiMessage::MidiMessage (const int byte1, { data[0] = (uint8) byte1; data[1] = (uint8) byte2; + + // check that the length matches the data.. + jassert (getMessageLengthFromFirstByte ((uint8) byte1) == 2); } MidiMessage::MidiMessage (const int byte1, @@ -106,6 +140,9 @@ MidiMessage::MidiMessage (const int byte1, data[0] = (uint8) byte1; data[1] = (uint8) byte2; data[2] = (uint8) byte3; + + // check that the length matches the data.. + jassert (getMessageLengthFromFirstByte ((uint8) byte1) == 3); } MidiMessage::MidiMessage (const MidiMessage& other) throw() @@ -201,17 +238,7 @@ MidiMessage::MidiMessage (const uint8* src, } else { - static const char messageLengths[] = { - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 1, 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - - size = messageLengths [byte - 0x80]; + size = getMessageLengthFromFirstByte ((uint8) byte); *data = (uint8) byte; if (size > 1) diff --git a/src/juce_appframework/audio/midi/juce_MidiMessage.h b/src/juce_appframework/audio/midi/juce_MidiMessage.h index 5388058963..3893541c90 100644 --- a/src/juce_appframework/audio/midi/juce_MidiMessage.h +++ b/src/juce_appframework/audio/midi/juce_MidiMessage.h @@ -844,6 +844,13 @@ public: static int readVariableLengthVal (const uint8* data, int& numBytesUsed) throw(); + /** Based on the first byte of a short midi message, this uses a lookup table + to return the message length (either 1, 2, or 3 bytes). + + The value passed in must be 0x80 or higher. + */ + static int getMessageLengthFromFirstByte (const uint8 firstByte) throw(); + //============================================================================== /** Returns the name of a midi note number.