| @@ -161,6 +161,7 @@ OBJECTS := \ | |||
| $(OBJDIR)/juce_AudioDeviceManager.o \ | |||
| $(OBJDIR)/juce_AudioIODevice.o \ | |||
| $(OBJDIR)/juce_AudioIODeviceType.o \ | |||
| $(OBJDIR)/juce_MidiOutput.o \ | |||
| $(OBJDIR)/juce_Sampler.o \ | |||
| $(OBJDIR)/juce_Synthesiser.o \ | |||
| $(OBJDIR)/juce_FileBasedDocument.o \ | |||
| @@ -1062,6 +1063,11 @@ $(OBJDIR)/juce_AudioIODeviceType.o: ../../src/juce_appframework/audio/devices/ju | |||
| @echo $(notdir $<) | |||
| @$(CXX) $(CXXFLAGS) -o $@ -c $< | |||
| $(OBJDIR)/juce_MidiOutput.o: ../../src/juce_appframework/audio/devices/juce_MidiOutput.cpp | |||
| -@$(CMD_MKOBJDIR) | |||
| @echo $(notdir $<) | |||
| @$(CXX) $(CXXFLAGS) -o $@ -c $< | |||
| $(OBJDIR)/juce_Sampler.o: ../../src/juce_appframework/audio/synthesisers/juce_Sampler.cpp | |||
| -@$(CMD_MKOBJDIR) | |||
| @echo $(notdir $<) | |||
| @@ -264,11 +264,6 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName) | |||
| return newDevice; | |||
| } | |||
| MidiOutput::MidiOutput() | |||
| : internal (0) | |||
| { | |||
| } | |||
| MidiOutput::~MidiOutput() | |||
| { | |||
| MidiOutputDevice* const device = (MidiOutputDevice*) internal; | |||
| @@ -9,6 +9,7 @@ | |||
| /* Begin PBXBuildFile section */ | |||
| 84052DE408D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */; }; | |||
| 84052DE508D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */; }; | |||
| 8406AA5A0C4BDF90003A0D6A /* juce_MidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */; }; | |||
| 8406C44609642CE100C99145 /* juce_LowLevelGraphicsContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 8406C44309642CE100C99145 /* juce_LowLevelGraphicsContext.h */; }; | |||
| 8406C44709642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8406C44409642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.cpp */; settings = {COMPILER_FLAGS = "-O3"; }; }; | |||
| 8406C44809642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8406C44509642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.h */; }; | |||
| @@ -650,6 +651,7 @@ | |||
| /* Begin PBXFileReference section */ | |||
| 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ToneGeneratorAudioSource.cpp; sourceTree = "<group>"; }; | |||
| 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_ToneGeneratorAudioSource.h; sourceTree = "<group>"; }; | |||
| 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_MidiOutput.cpp; sourceTree = "<group>"; }; | |||
| 8406C44309642CE100C99145 /* juce_LowLevelGraphicsContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_LowLevelGraphicsContext.h; sourceTree = "<group>"; }; | |||
| 8406C44409642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_LowLevelGraphicsSoftwareRenderer.cpp; sourceTree = "<group>"; }; | |||
| 8406C44509642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_LowLevelGraphicsSoftwareRenderer.h; sourceTree = "<group>"; }; | |||
| @@ -1355,6 +1357,7 @@ | |||
| 84198B0A096D8E2B0022A439 /* juce_AudioDeviceManager.cpp */, | |||
| 84198B0B096D8E2B0022A439 /* juce_AudioDeviceManager.h */, | |||
| 84198B0D096D8E2B0022A439 /* juce_MidiInput.h */, | |||
| 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */, | |||
| 84198B0E096D8E2B0022A439 /* juce_MidiOutput.h */, | |||
| ); | |||
| path = devices; | |||
| @@ -3114,6 +3117,7 @@ | |||
| 842D3D0E0C0D7CF200E9FFE4 /* juce_MenuBarModel.cpp in Sources */, | |||
| 847F72DB0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp in Sources */, | |||
| 847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */, | |||
| 8406AA5A0C4BDF90003A0D6A /* juce_MidiOutput.cpp in Sources */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| @@ -285,10 +285,6 @@ MidiOutput* MidiOutput::openDevice (int index) | |||
| return mo; | |||
| } | |||
| MidiOutput::MidiOutput() | |||
| { | |||
| } | |||
| MidiOutput::~MidiOutput() | |||
| { | |||
| MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; | |||
| @@ -551,10 +551,6 @@ MidiOutput* MidiOutput::openDevice (int index) | |||
| return 0; | |||
| } | |||
| MidiOutput::MidiOutput() | |||
| { | |||
| } | |||
| MidiOutput::~MidiOutput() | |||
| { | |||
| MidiOutHandle* const h = (MidiOutHandle*) internal; | |||
| @@ -1057,6 +1057,10 @@ | |||
| RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiInput.h" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiOutput.cpp" | |||
| > | |||
| </File> | |||
| <File | |||
| RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiOutput.h" | |||
| > | |||
| @@ -15,6 +15,7 @@ Changelist for version 1.44 | |||
| - added some virtual methods to TextEditor to allow customisation of its popup menu. | |||
| - added a Component::setExplicitFocusOrder() method for specifying the order in which components have their focus traversed, and added Jucer support for setting this value. | |||
| - made slider skew factor editable in the jucer | |||
| - added a background thread to the MidiOutput class, so it can be given a batch of midi events and will dispatch them itself based on their timestamps. | |||
| ============================================================================== | |||
| Changelist for version 1.43 | |||
| @@ -0,0 +1,178 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-7 by Raw Material Software ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the | |||
| GNU General Public License, as published by the Free Software Foundation; | |||
| either version 2 of the License, or (at your option) any later version. | |||
| JUCE is distributed in the hope that it will be useful, | |||
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| GNU General Public License for more details. | |||
| You should have received a copy of the GNU General Public License | |||
| along with JUCE; if not, visit www.gnu.org/licenses or write to the | |||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||
| Boston, MA 02111-1307 USA | |||
| ------------------------------------------------------------------------------ | |||
| If you'd like to release a closed-source product which uses JUCE, commercial | |||
| licenses are also available: visit www.rawmaterialsoftware.com/juce for | |||
| more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "../../../juce_core/basics/juce_StandardHeader.h" | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "juce_MidiOutput.h" | |||
| #include "../../../juce_core/threads/juce_ScopedLock.h" | |||
| #include "../../../juce_core/basics/juce_Time.h" | |||
| //============================================================================== | |||
| MidiOutput::MidiOutput() throw() | |||
| : Thread ("midi out"), | |||
| internal (0), | |||
| firstMessage (0) | |||
| { | |||
| } | |||
| MidiOutput::PendingMessage::PendingMessage (const uint8* const data, | |||
| const int len, | |||
| const double sampleNumber) throw() | |||
| : message (data, len, sampleNumber) | |||
| { | |||
| } | |||
| void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, | |||
| const double millisecondCounterToStartAt, | |||
| double samplesPerSecondForBuffer) throw() | |||
| { | |||
| // You've got to call startBackgroundThread() for this to actually work.. | |||
| jassert (isThreadRunning()); | |||
| // this needs to be a value in the future - RTFM for this method! | |||
| jassert (millisecondCounterToStartAt > 0); | |||
| samplesPerSecondForBuffer *= 0.001; | |||
| MidiBuffer::Iterator i (buffer); | |||
| const uint8* data; | |||
| int len, time; | |||
| while (i.getNextEvent (data, len, time)) | |||
| { | |||
| const double eventTime = millisecondCounterToStartAt + samplesPerSecondForBuffer * time; | |||
| PendingMessage* const m | |||
| = new PendingMessage (data, len, eventTime); | |||
| const ScopedLock sl (lock); | |||
| if (firstMessage == 0) | |||
| { | |||
| firstMessage = m; | |||
| m->next = 0; | |||
| } | |||
| else | |||
| { | |||
| PendingMessage* mm = firstMessage; | |||
| while (mm->next != 0 && mm->next->message.getTimeStamp() <= eventTime) | |||
| mm = mm->next; | |||
| m->next = mm->next; | |||
| mm->next = m; | |||
| } | |||
| } | |||
| notify(); | |||
| } | |||
| void MidiOutput::clearAllPendingMessages() throw() | |||
| { | |||
| const ScopedLock sl (lock); | |||
| while (firstMessage != 0) | |||
| { | |||
| PendingMessage* const m = firstMessage; | |||
| firstMessage = firstMessage->next; | |||
| delete m; | |||
| } | |||
| } | |||
| void MidiOutput::startBackgroundThread() throw() | |||
| { | |||
| startThread (9); | |||
| } | |||
| void MidiOutput::stopBackgroundThread() throw() | |||
| { | |||
| stopThread (5000); | |||
| } | |||
| void MidiOutput::run() | |||
| { | |||
| while (! threadShouldExit()) | |||
| { | |||
| uint32 now = Time::getMillisecondCounter(); | |||
| uint32 eventTime = 0; | |||
| uint32 timeToWait = 500; | |||
| lock.enter(); | |||
| PendingMessage* message = firstMessage; | |||
| if (message != 0) | |||
| { | |||
| eventTime = roundDoubleToInt (message->message.getTimeStamp()); | |||
| if (eventTime > now + 20) | |||
| { | |||
| timeToWait = jmax (10, eventTime - now - 100); | |||
| message = 0; | |||
| } | |||
| else | |||
| { | |||
| firstMessage = message->next; | |||
| } | |||
| } | |||
| lock.exit(); | |||
| if (message != 0) | |||
| { | |||
| if (eventTime > now) | |||
| { | |||
| Time::waitForMillisecondCounter (eventTime); | |||
| if (threadShouldExit()) | |||
| break; | |||
| } | |||
| if (eventTime > now - 200) | |||
| sendMessageNow (message->message); | |||
| delete message; | |||
| } | |||
| else | |||
| { | |||
| jassert (timeToWait < 1000 * 30); | |||
| wait (timeToWait); | |||
| } | |||
| } | |||
| clearAllPendingMessages(); | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -33,7 +33,9 @@ | |||
| #define __JUCE_MIDIOUTPUT_JUCEHEADER__ | |||
| #include "../../../juce_core/text/juce_StringArray.h" | |||
| #include "../../../juce_core/threads/juce_Thread.h" | |||
| #include "../midi/juce_MidiMessage.h" | |||
| #include "../midi/juce_MidiBuffer.h" | |||
| //============================================================================== | |||
| @@ -45,7 +47,7 @@ | |||
| @see MidiInput | |||
| */ | |||
| class JUCE_API MidiOutput | |||
| class JUCE_API MidiOutput : private Thread | |||
| { | |||
| public: | |||
| //============================================================================== | |||
| @@ -103,6 +105,7 @@ public: | |||
| /** Sends a midi reset to the device. */ | |||
| void reset(); | |||
| //============================================================================== | |||
| /** Returns the current volume setting for this device. */ | |||
| bool getVolume (float& leftVol, | |||
| @@ -112,6 +115,44 @@ public: | |||
| void setVolume (float leftVol, | |||
| float rightVol); | |||
| //============================================================================== | |||
| /** This lets you supply a block of messages that will be sent out at some point | |||
| in the future. | |||
| The MidiOutput class has an internal thread that can send out timestamped | |||
| messages - this appends a set of messages to its internal buffer, ready for | |||
| sending. | |||
| This will only work if you've already started the thread with startBackgroundThread(). | |||
| A time is supplied, at which the block of messages should be sent. This time uses | |||
| the same time base as Time::getMillisecondCounter(), and must be in the future. | |||
| The samplesPerSecondForBuffer parameter indicates the number of samples per second | |||
| used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the | |||
| samplesPerSecondForBuffer value is needed to convert this sample position to a | |||
| real time. | |||
| */ | |||
| void sendBlockOfMessages (const MidiBuffer& buffer, | |||
| const double millisecondCounterToStartAt, | |||
| double samplesPerSecondForBuffer) throw(); | |||
| /** Gets rid of any midi messages that had been added by sendBlockOfMessages(). | |||
| */ | |||
| void clearAllPendingMessages() throw(); | |||
| /** Starts up a background thread so that the device can send blocks of data. | |||
| Call this to get the device ready, before using sendBlockOfMessages(). | |||
| */ | |||
| void startBackgroundThread() throw(); | |||
| /** Stops the background thread, and clears any pending midi events. | |||
| @see startBackgroundThread | |||
| */ | |||
| void stopBackgroundThread() throw(); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| @@ -119,8 +160,23 @@ public: | |||
| private: | |||
| void* internal; | |||
| MidiOutput(); | |||
| struct PendingMessage | |||
| { | |||
| PendingMessage (const uint8* const data, const int len, const double sampleNumber) throw(); | |||
| MidiMessage message; | |||
| PendingMessage* next; | |||
| juce_UseDebuggingNewOperator | |||
| }; | |||
| CriticalSection lock; | |||
| PendingMessage* firstMessage; | |||
| MidiOutput() throw(); | |||
| MidiOutput (const MidiOutput&); | |||
| void run(); | |||
| }; | |||
| @@ -37,13 +37,13 @@ BEGIN_JUCE_NAMESPACE | |||
| //============================================================================== | |||
| MidiBuffer::MidiBuffer() | |||
| MidiBuffer::MidiBuffer() throw() | |||
| : ArrayAllocationBase <uint8> (32), | |||
| bytesUsed (0) | |||
| { | |||
| } | |||
| MidiBuffer::MidiBuffer (const MidiBuffer& other) | |||
| MidiBuffer::MidiBuffer (const MidiBuffer& other) throw() | |||
| : ArrayAllocationBase <uint8> (32), | |||
| bytesUsed (other.bytesUsed) | |||
| { | |||
| @@ -51,7 +51,7 @@ MidiBuffer::MidiBuffer (const MidiBuffer& other) | |||
| memcpy (elements, other.elements, bytesUsed); | |||
| } | |||
| const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) | |||
| const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw() | |||
| { | |||
| bytesUsed = other.bytesUsed; | |||
| ensureAllocatedSize (bytesUsed); | |||
| @@ -60,17 +60,17 @@ const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) | |||
| return *this; | |||
| } | |||
| MidiBuffer::~MidiBuffer() | |||
| MidiBuffer::~MidiBuffer() throw() | |||
| { | |||
| } | |||
| void MidiBuffer::clear() | |||
| void MidiBuffer::clear() throw() | |||
| { | |||
| bytesUsed = 0; | |||
| } | |||
| void MidiBuffer::clear (const int startSample, | |||
| const int numSamples) | |||
| const int numSamples) throw() | |||
| { | |||
| uint8* const start = findEventAfter (elements, startSample - 1); | |||
| uint8* const end = findEventAfter (start, startSample + numSamples - 1); | |||
| @@ -87,13 +87,13 @@ void MidiBuffer::clear (const int startSample, | |||
| } | |||
| void MidiBuffer::addEvent (const MidiMessage& m, | |||
| const int sampleNumber) | |||
| const int sampleNumber) throw() | |||
| { | |||
| addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber); | |||
| } | |||
| static int findActualEventLength (const uint8* const data, | |||
| const int maxBytes) | |||
| const int maxBytes) throw() | |||
| { | |||
| unsigned int byte = (unsigned int) *data; | |||
| @@ -125,7 +125,7 @@ static int findActualEventLength (const uint8* const data, | |||
| void MidiBuffer::addEvent (const uint8* const newData, | |||
| const int maxBytes, | |||
| const int sampleNumber) | |||
| const int sampleNumber) throw() | |||
| { | |||
| const int numBytes = findActualEventLength (newData, maxBytes); | |||
| @@ -155,7 +155,7 @@ void MidiBuffer::addEvent (const uint8* const newData, | |||
| void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | |||
| const int startSample, | |||
| const int numSamples, | |||
| const int sampleDeltaToAdd) | |||
| const int sampleDeltaToAdd) throw() | |||
| { | |||
| Iterator i (otherBuffer); | |||
| i.setNextSamplePosition (startSample); | |||
| @@ -170,12 +170,12 @@ void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | |||
| } | |||
| } | |||
| bool MidiBuffer::isEmpty() const | |||
| bool MidiBuffer::isEmpty() const throw() | |||
| { | |||
| return bytesUsed == 0; | |||
| } | |||
| int MidiBuffer::getNumEvents() const | |||
| int MidiBuffer::getNumEvents() const throw() | |||
| { | |||
| int n = 0; | |||
| const uint8* d = elements; | |||
| @@ -191,12 +191,12 @@ int MidiBuffer::getNumEvents() const | |||
| return n; | |||
| } | |||
| int MidiBuffer::getFirstEventTime() const | |||
| int MidiBuffer::getFirstEventTime() const throw() | |||
| { | |||
| return (bytesUsed > 0) ? *(const int*) elements : 0; | |||
| } | |||
| int MidiBuffer::getLastEventTime() const | |||
| int MidiBuffer::getLastEventTime() const throw() | |||
| { | |||
| if (bytesUsed == 0) | |||
| return 0; | |||
| @@ -215,7 +215,7 @@ int MidiBuffer::getLastEventTime() const | |||
| } | |||
| } | |||
| uint8* MidiBuffer::findEventAfter (uint8* d, const int samplePosition) const | |||
| uint8* MidiBuffer::findEventAfter (uint8* d, const int samplePosition) const throw() | |||
| { | |||
| const uint8* const endData = elements + bytesUsed; | |||
| @@ -229,18 +229,18 @@ uint8* MidiBuffer::findEventAfter (uint8* d, const int samplePosition) const | |||
| } | |||
| //============================================================================== | |||
| MidiBuffer::Iterator::Iterator (const MidiBuffer& buffer) | |||
| MidiBuffer::Iterator::Iterator (const MidiBuffer& buffer) throw() | |||
| : buffer (buffer), | |||
| data (buffer.elements) | |||
| { | |||
| } | |||
| MidiBuffer::Iterator::~Iterator() | |||
| MidiBuffer::Iterator::~Iterator() throw() | |||
| { | |||
| } | |||
| //============================================================================== | |||
| void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) | |||
| void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) throw() | |||
| { | |||
| data = buffer.elements; | |||
| const uint8* dataEnd = buffer.elements + buffer.bytesUsed; | |||
| @@ -254,7 +254,7 @@ void MidiBuffer::Iterator::setNextSamplePosition (const int samplePosition) | |||
| bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, | |||
| int& numBytes, | |||
| int& samplePosition) | |||
| int& samplePosition) throw() | |||
| { | |||
| if (data >= buffer.elements + buffer.bytesUsed) | |||
| return false; | |||
| @@ -270,7 +270,7 @@ bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, | |||
| } | |||
| bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, | |||
| int& samplePosition) | |||
| int& samplePosition) throw() | |||
| { | |||
| if (data >= buffer.elements + buffer.bytesUsed) | |||
| return false; | |||
| @@ -50,20 +50,20 @@ class JUCE_API MidiBuffer : private ArrayAllocationBase <uint8> | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an empty MidiBuffer. */ | |||
| MidiBuffer(); | |||
| MidiBuffer() throw(); | |||
| /** Creates a copy of another MidiBuffer. */ | |||
| MidiBuffer (const MidiBuffer& other); | |||
| MidiBuffer (const MidiBuffer& other) throw(); | |||
| /** Makes a copy of another MidiBuffer. */ | |||
| const MidiBuffer& operator= (const MidiBuffer& other); | |||
| const MidiBuffer& operator= (const MidiBuffer& other) throw(); | |||
| /** Destructor */ | |||
| ~MidiBuffer(); | |||
| ~MidiBuffer() throw(); | |||
| //============================================================================== | |||
| /** Removes all events from the buffer. */ | |||
| void clear(); | |||
| void clear() throw(); | |||
| /** Removes all events between two times from the buffer. | |||
| @@ -71,13 +71,13 @@ public: | |||
| be removed. | |||
| */ | |||
| void clear (const int start, | |||
| const int numSamples); | |||
| const int numSamples) throw(); | |||
| /** Returns true if the buffer is empty. | |||
| To actually retrieve the events, use a MidiBuffer::Iterator object | |||
| */ | |||
| bool isEmpty() const; | |||
| bool isEmpty() const throw(); | |||
| /** Counts the number of events in the buffer. | |||
| @@ -85,7 +85,7 @@ public: | |||
| the events, so you might prefer to call isEmpty() if that's all you need | |||
| to know. | |||
| */ | |||
| int getNumEvents() const; | |||
| int getNumEvents() const throw(); | |||
| /** Adds an event to the buffer. | |||
| @@ -99,7 +99,7 @@ public: | |||
| To retrieve events, use a MidiBuffer::Iterator object | |||
| */ | |||
| void addEvent (const MidiMessage& midiMessage, | |||
| const int sampleNumber); | |||
| const int sampleNumber) throw(); | |||
| /** Adds an event to the buffer from raw midi data. | |||
| @@ -119,7 +119,7 @@ public: | |||
| */ | |||
| void addEvent (const uint8* const rawMidiData, | |||
| const int maxBytesOfMidiData, | |||
| const int sampleNumber); | |||
| const int sampleNumber) throw(); | |||
| /** Adds some events from another buffer to this one. | |||
| @@ -138,19 +138,19 @@ public: | |||
| void addEvents (const MidiBuffer& otherBuffer, | |||
| const int startSample, | |||
| const int numSamples, | |||
| const int sampleDeltaToAdd); | |||
| const int sampleDeltaToAdd) throw(); | |||
| /** Returns the sample number of the first event in the buffer. | |||
| If the buffer's empty, this will just return 0. | |||
| */ | |||
| int getFirstEventTime() const; | |||
| int getFirstEventTime() const throw(); | |||
| /** Returns the sample number of the last event in the buffer. | |||
| If the buffer's empty, this will just return 0. | |||
| */ | |||
| int getLastEventTime() const; | |||
| int getLastEventTime() const throw(); | |||
| //============================================================================== | |||
| /** | |||
| @@ -166,16 +166,16 @@ public: | |||
| public: | |||
| //============================================================================== | |||
| /** Creates an Iterator for this MidiBuffer. */ | |||
| Iterator (const MidiBuffer& buffer); | |||
| Iterator (const MidiBuffer& buffer) throw(); | |||
| /** Destructor. */ | |||
| ~Iterator(); | |||
| ~Iterator() throw(); | |||
| //============================================================================== | |||
| /** Repositions the iterator so that the next event retrieved will be the first | |||
| one whose sample position is at greater than or equal to the given position. | |||
| */ | |||
| void setNextSamplePosition (const int samplePosition); | |||
| void setNextSamplePosition (const int samplePosition) throw(); | |||
| /** Retrieves a copy of the next event from the buffer. | |||
| @@ -186,7 +186,7 @@ public: | |||
| the end of the buffer | |||
| */ | |||
| bool getNextEvent (MidiMessage& result, | |||
| int& samplePosition); | |||
| int& samplePosition) throw(); | |||
| /** Retrieves the next event from the buffer. | |||
| @@ -202,7 +202,7 @@ public: | |||
| */ | |||
| bool getNextEvent (const uint8* &midiData, | |||
| int& numBytesOfMidiData, | |||
| int& samplePosition); | |||
| int& samplePosition) throw(); | |||
| //============================================================================== | |||
| juce_UseDebuggingNewOperator | |||
| @@ -223,7 +223,7 @@ private: | |||
| friend class MidiBuffer::Iterator; | |||
| int bytesUsed; | |||
| uint8* findEventAfter (uint8* d, const int samplePosition) const; | |||
| uint8* findEventAfter (uint8* d, const int samplePosition) const throw(); | |||
| }; | |||
| @@ -100,7 +100,7 @@ MidiMessage::MidiMessage (const uint8* const d, | |||
| memcpy (data, d, dataSize); | |||
| // check that the length matches the data.. | |||
| jassert (size > 3 || getMessageLengthFromFirstByte (*d) == size); | |||
| jassert (size > 3 || *d >= 0xf0 || getMessageLengthFromFirstByte (*d) == size); | |||
| } | |||
| MidiMessage::MidiMessage (const int byte1, | |||
| @@ -473,6 +473,7 @@ const MidiMessage MidiMessage::controllerEvent (const int channel, | |||
| const int controllerType, | |||
| const int value) throw() | |||
| { | |||
| // the channel must be between 1 and 16 inclusive | |||
| jassert (channel > 0 && channel <= 16); | |||
| return MidiMessage (0xb0 | jlimit (0, 15, channel - 1), | |||