| @@ -161,6 +161,7 @@ OBJECTS := \ | |||||
| $(OBJDIR)/juce_AudioDeviceManager.o \ | $(OBJDIR)/juce_AudioDeviceManager.o \ | ||||
| $(OBJDIR)/juce_AudioIODevice.o \ | $(OBJDIR)/juce_AudioIODevice.o \ | ||||
| $(OBJDIR)/juce_AudioIODeviceType.o \ | $(OBJDIR)/juce_AudioIODeviceType.o \ | ||||
| $(OBJDIR)/juce_MidiOutput.o \ | |||||
| $(OBJDIR)/juce_Sampler.o \ | $(OBJDIR)/juce_Sampler.o \ | ||||
| $(OBJDIR)/juce_Synthesiser.o \ | $(OBJDIR)/juce_Synthesiser.o \ | ||||
| $(OBJDIR)/juce_FileBasedDocument.o \ | $(OBJDIR)/juce_FileBasedDocument.o \ | ||||
| @@ -1062,6 +1063,11 @@ $(OBJDIR)/juce_AudioIODeviceType.o: ../../src/juce_appframework/audio/devices/ju | |||||
| @echo $(notdir $<) | @echo $(notdir $<) | ||||
| @$(CXX) $(CXXFLAGS) -o $@ -c $< | @$(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 | $(OBJDIR)/juce_Sampler.o: ../../src/juce_appframework/audio/synthesisers/juce_Sampler.cpp | ||||
| -@$(CMD_MKOBJDIR) | -@$(CMD_MKOBJDIR) | ||||
| @echo $(notdir $<) | @echo $(notdir $<) | ||||
| @@ -264,11 +264,6 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName) | |||||
| return newDevice; | return newDevice; | ||||
| } | } | ||||
| MidiOutput::MidiOutput() | |||||
| : internal (0) | |||||
| { | |||||
| } | |||||
| MidiOutput::~MidiOutput() | MidiOutput::~MidiOutput() | ||||
| { | { | ||||
| MidiOutputDevice* const device = (MidiOutputDevice*) internal; | MidiOutputDevice* const device = (MidiOutputDevice*) internal; | ||||
| @@ -9,6 +9,7 @@ | |||||
| /* Begin PBXBuildFile section */ | /* Begin PBXBuildFile section */ | ||||
| 84052DE408D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */; }; | 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 */; }; | 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 */; }; | 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"; }; }; | 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 */; }; | 8406C44809642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8406C44509642CE100C99145 /* juce_LowLevelGraphicsSoftwareRenderer.h */; }; | ||||
| @@ -650,6 +651,7 @@ | |||||
| /* Begin PBXFileReference section */ | /* Begin PBXFileReference section */ | ||||
| 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ToneGeneratorAudioSource.cpp; sourceTree = "<group>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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>"; }; | 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 */, | 84198B0A096D8E2B0022A439 /* juce_AudioDeviceManager.cpp */, | ||||
| 84198B0B096D8E2B0022A439 /* juce_AudioDeviceManager.h */, | 84198B0B096D8E2B0022A439 /* juce_AudioDeviceManager.h */, | ||||
| 84198B0D096D8E2B0022A439 /* juce_MidiInput.h */, | 84198B0D096D8E2B0022A439 /* juce_MidiInput.h */, | ||||
| 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */, | |||||
| 84198B0E096D8E2B0022A439 /* juce_MidiOutput.h */, | 84198B0E096D8E2B0022A439 /* juce_MidiOutput.h */, | ||||
| ); | ); | ||||
| path = devices; | path = devices; | ||||
| @@ -3114,6 +3117,7 @@ | |||||
| 842D3D0E0C0D7CF200E9FFE4 /* juce_MenuBarModel.cpp in Sources */, | 842D3D0E0C0D7CF200E9FFE4 /* juce_MenuBarModel.cpp in Sources */, | ||||
| 847F72DB0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp in Sources */, | 847F72DB0C2702A000CBECEC /* juce_DirectoryContentsDisplayComponent.cpp in Sources */, | ||||
| 847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */, | 847F72DD0C2702A000CBECEC /* juce_FileTreeComponent.cpp in Sources */, | ||||
| 8406AA5A0C4BDF90003A0D6A /* juce_MidiOutput.cpp in Sources */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| @@ -285,10 +285,6 @@ MidiOutput* MidiOutput::openDevice (int index) | |||||
| return mo; | return mo; | ||||
| } | } | ||||
| MidiOutput::MidiOutput() | |||||
| { | |||||
| } | |||||
| MidiOutput::~MidiOutput() | MidiOutput::~MidiOutput() | ||||
| { | { | ||||
| MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; | MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal; | ||||
| @@ -551,10 +551,6 @@ MidiOutput* MidiOutput::openDevice (int index) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| MidiOutput::MidiOutput() | |||||
| { | |||||
| } | |||||
| MidiOutput::~MidiOutput() | MidiOutput::~MidiOutput() | ||||
| { | { | ||||
| MidiOutHandle* const h = (MidiOutHandle*) internal; | MidiOutHandle* const h = (MidiOutHandle*) internal; | ||||
| @@ -1057,6 +1057,10 @@ | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiInput.h" | RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiInput.h" | ||||
| > | > | ||||
| </File> | </File> | ||||
| <File | |||||
| RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiOutput.cpp" | |||||
| > | |||||
| </File> | |||||
| <File | <File | ||||
| RelativePath="..\..\..\src\juce_appframework\audio\devices\juce_MidiOutput.h" | 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 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. | - 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 | - 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 | 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__ | #define __JUCE_MIDIOUTPUT_JUCEHEADER__ | ||||
| #include "../../../juce_core/text/juce_StringArray.h" | #include "../../../juce_core/text/juce_StringArray.h" | ||||
| #include "../../../juce_core/threads/juce_Thread.h" | |||||
| #include "../midi/juce_MidiMessage.h" | #include "../midi/juce_MidiMessage.h" | ||||
| #include "../midi/juce_MidiBuffer.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -45,7 +47,7 @@ | |||||
| @see MidiInput | @see MidiInput | ||||
| */ | */ | ||||
| class JUCE_API MidiOutput | |||||
| class JUCE_API MidiOutput : private Thread | |||||
| { | { | ||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -103,6 +105,7 @@ public: | |||||
| /** Sends a midi reset to the device. */ | /** Sends a midi reset to the device. */ | ||||
| void reset(); | void reset(); | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the current volume setting for this device. */ | /** Returns the current volume setting for this device. */ | ||||
| bool getVolume (float& leftVol, | bool getVolume (float& leftVol, | ||||
| @@ -112,6 +115,44 @@ public: | |||||
| void setVolume (float leftVol, | void setVolume (float leftVol, | ||||
| float rightVol); | 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 | juce_UseDebuggingNewOperator | ||||
| @@ -119,8 +160,23 @@ public: | |||||
| private: | private: | ||||
| void* internal; | 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&); | MidiOutput (const MidiOutput&); | ||||
| void run(); | |||||
| }; | }; | ||||
| @@ -37,13 +37,13 @@ BEGIN_JUCE_NAMESPACE | |||||
| //============================================================================== | //============================================================================== | ||||
| MidiBuffer::MidiBuffer() | |||||
| MidiBuffer::MidiBuffer() throw() | |||||
| : ArrayAllocationBase <uint8> (32), | : ArrayAllocationBase <uint8> (32), | ||||
| bytesUsed (0) | bytesUsed (0) | ||||
| { | { | ||||
| } | } | ||||
| MidiBuffer::MidiBuffer (const MidiBuffer& other) | |||||
| MidiBuffer::MidiBuffer (const MidiBuffer& other) throw() | |||||
| : ArrayAllocationBase <uint8> (32), | : ArrayAllocationBase <uint8> (32), | ||||
| bytesUsed (other.bytesUsed) | bytesUsed (other.bytesUsed) | ||||
| { | { | ||||
| @@ -51,7 +51,7 @@ MidiBuffer::MidiBuffer (const MidiBuffer& other) | |||||
| memcpy (elements, other.elements, bytesUsed); | memcpy (elements, other.elements, bytesUsed); | ||||
| } | } | ||||
| const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) | |||||
| const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw() | |||||
| { | { | ||||
| bytesUsed = other.bytesUsed; | bytesUsed = other.bytesUsed; | ||||
| ensureAllocatedSize (bytesUsed); | ensureAllocatedSize (bytesUsed); | ||||
| @@ -60,17 +60,17 @@ const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| MidiBuffer::~MidiBuffer() | |||||
| MidiBuffer::~MidiBuffer() throw() | |||||
| { | { | ||||
| } | } | ||||
| void MidiBuffer::clear() | |||||
| void MidiBuffer::clear() throw() | |||||
| { | { | ||||
| bytesUsed = 0; | bytesUsed = 0; | ||||
| } | } | ||||
| void MidiBuffer::clear (const int startSample, | void MidiBuffer::clear (const int startSample, | ||||
| const int numSamples) | |||||
| const int numSamples) throw() | |||||
| { | { | ||||
| uint8* const start = findEventAfter (elements, startSample - 1); | uint8* const start = findEventAfter (elements, startSample - 1); | ||||
| uint8* const end = findEventAfter (start, startSample + numSamples - 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, | void MidiBuffer::addEvent (const MidiMessage& m, | ||||
| const int sampleNumber) | |||||
| const int sampleNumber) throw() | |||||
| { | { | ||||
| addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber); | addEvent (m.getRawData(), m.getRawDataSize(), sampleNumber); | ||||
| } | } | ||||
| static int findActualEventLength (const uint8* const data, | static int findActualEventLength (const uint8* const data, | ||||
| const int maxBytes) | |||||
| const int maxBytes) throw() | |||||
| { | { | ||||
| unsigned int byte = (unsigned int) *data; | unsigned int byte = (unsigned int) *data; | ||||
| @@ -125,7 +125,7 @@ static int findActualEventLength (const uint8* const data, | |||||
| void MidiBuffer::addEvent (const uint8* const newData, | void MidiBuffer::addEvent (const uint8* const newData, | ||||
| const int maxBytes, | const int maxBytes, | ||||
| const int sampleNumber) | |||||
| const int sampleNumber) throw() | |||||
| { | { | ||||
| const int numBytes = findActualEventLength (newData, maxBytes); | const int numBytes = findActualEventLength (newData, maxBytes); | ||||
| @@ -155,7 +155,7 @@ void MidiBuffer::addEvent (const uint8* const newData, | |||||
| void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | void MidiBuffer::addEvents (const MidiBuffer& otherBuffer, | ||||
| const int startSample, | const int startSample, | ||||
| const int numSamples, | const int numSamples, | ||||
| const int sampleDeltaToAdd) | |||||
| const int sampleDeltaToAdd) throw() | |||||
| { | { | ||||
| Iterator i (otherBuffer); | Iterator i (otherBuffer); | ||||
| i.setNextSamplePosition (startSample); | 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; | return bytesUsed == 0; | ||||
| } | } | ||||
| int MidiBuffer::getNumEvents() const | |||||
| int MidiBuffer::getNumEvents() const throw() | |||||
| { | { | ||||
| int n = 0; | int n = 0; | ||||
| const uint8* d = elements; | const uint8* d = elements; | ||||
| @@ -191,12 +191,12 @@ int MidiBuffer::getNumEvents() const | |||||
| return n; | return n; | ||||
| } | } | ||||
| int MidiBuffer::getFirstEventTime() const | |||||
| int MidiBuffer::getFirstEventTime() const throw() | |||||
| { | { | ||||
| return (bytesUsed > 0) ? *(const int*) elements : 0; | return (bytesUsed > 0) ? *(const int*) elements : 0; | ||||
| } | } | ||||
| int MidiBuffer::getLastEventTime() const | |||||
| int MidiBuffer::getLastEventTime() const throw() | |||||
| { | { | ||||
| if (bytesUsed == 0) | if (bytesUsed == 0) | ||||
| return 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; | 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), | : buffer (buffer), | ||||
| data (buffer.elements) | 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; | data = buffer.elements; | ||||
| const uint8* dataEnd = buffer.elements + buffer.bytesUsed; | 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, | bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, | ||||
| int& numBytes, | int& numBytes, | ||||
| int& samplePosition) | |||||
| int& samplePosition) throw() | |||||
| { | { | ||||
| if (data >= buffer.elements + buffer.bytesUsed) | if (data >= buffer.elements + buffer.bytesUsed) | ||||
| return false; | return false; | ||||
| @@ -270,7 +270,7 @@ bool MidiBuffer::Iterator::getNextEvent (const uint8* &midiData, | |||||
| } | } | ||||
| bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, | bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, | ||||
| int& samplePosition) | |||||
| int& samplePosition) throw() | |||||
| { | { | ||||
| if (data >= buffer.elements + buffer.bytesUsed) | if (data >= buffer.elements + buffer.bytesUsed) | ||||
| return false; | return false; | ||||
| @@ -50,20 +50,20 @@ class JUCE_API MidiBuffer : private ArrayAllocationBase <uint8> | |||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates an empty MidiBuffer. */ | /** Creates an empty MidiBuffer. */ | ||||
| MidiBuffer(); | |||||
| MidiBuffer() throw(); | |||||
| /** Creates a copy of another MidiBuffer. */ | /** Creates a copy of another MidiBuffer. */ | ||||
| MidiBuffer (const MidiBuffer& other); | |||||
| MidiBuffer (const MidiBuffer& other) throw(); | |||||
| /** Makes a copy of another MidiBuffer. */ | /** Makes a copy of another MidiBuffer. */ | ||||
| const MidiBuffer& operator= (const MidiBuffer& other); | |||||
| const MidiBuffer& operator= (const MidiBuffer& other) throw(); | |||||
| /** Destructor */ | /** Destructor */ | ||||
| ~MidiBuffer(); | |||||
| ~MidiBuffer() throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Removes all events from the buffer. */ | /** Removes all events from the buffer. */ | ||||
| void clear(); | |||||
| void clear() throw(); | |||||
| /** Removes all events between two times from the buffer. | /** Removes all events between two times from the buffer. | ||||
| @@ -71,13 +71,13 @@ public: | |||||
| be removed. | be removed. | ||||
| */ | */ | ||||
| void clear (const int start, | void clear (const int start, | ||||
| const int numSamples); | |||||
| const int numSamples) throw(); | |||||
| /** Returns true if the buffer is empty. | /** Returns true if the buffer is empty. | ||||
| To actually retrieve the events, use a MidiBuffer::Iterator object | 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. | /** 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 | the events, so you might prefer to call isEmpty() if that's all you need | ||||
| to know. | to know. | ||||
| */ | */ | ||||
| int getNumEvents() const; | |||||
| int getNumEvents() const throw(); | |||||
| /** Adds an event to the buffer. | /** Adds an event to the buffer. | ||||
| @@ -99,7 +99,7 @@ public: | |||||
| To retrieve events, use a MidiBuffer::Iterator object | To retrieve events, use a MidiBuffer::Iterator object | ||||
| */ | */ | ||||
| void addEvent (const MidiMessage& midiMessage, | void addEvent (const MidiMessage& midiMessage, | ||||
| const int sampleNumber); | |||||
| const int sampleNumber) throw(); | |||||
| /** Adds an event to the buffer from raw midi data. | /** Adds an event to the buffer from raw midi data. | ||||
| @@ -119,7 +119,7 @@ public: | |||||
| */ | */ | ||||
| void addEvent (const uint8* const rawMidiData, | void addEvent (const uint8* const rawMidiData, | ||||
| const int maxBytesOfMidiData, | const int maxBytesOfMidiData, | ||||
| const int sampleNumber); | |||||
| const int sampleNumber) throw(); | |||||
| /** Adds some events from another buffer to this one. | /** Adds some events from another buffer to this one. | ||||
| @@ -138,19 +138,19 @@ public: | |||||
| void addEvents (const MidiBuffer& otherBuffer, | void addEvents (const MidiBuffer& otherBuffer, | ||||
| const int startSample, | const int startSample, | ||||
| const int numSamples, | const int numSamples, | ||||
| const int sampleDeltaToAdd); | |||||
| const int sampleDeltaToAdd) throw(); | |||||
| /** Returns the sample number of the first event in the buffer. | /** Returns the sample number of the first event in the buffer. | ||||
| If the buffer's empty, this will just return 0. | 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. | /** Returns the sample number of the last event in the buffer. | ||||
| If the buffer's empty, this will just return 0. | If the buffer's empty, this will just return 0. | ||||
| */ | */ | ||||
| int getLastEventTime() const; | |||||
| int getLastEventTime() const throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** | /** | ||||
| @@ -166,16 +166,16 @@ public: | |||||
| public: | public: | ||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates an Iterator for this MidiBuffer. */ | /** Creates an Iterator for this MidiBuffer. */ | ||||
| Iterator (const MidiBuffer& buffer); | |||||
| Iterator (const MidiBuffer& buffer) throw(); | |||||
| /** Destructor. */ | /** Destructor. */ | ||||
| ~Iterator(); | |||||
| ~Iterator() throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Repositions the iterator so that the next event retrieved will be the first | /** 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. | 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. | /** Retrieves a copy of the next event from the buffer. | ||||
| @@ -186,7 +186,7 @@ public: | |||||
| the end of the buffer | the end of the buffer | ||||
| */ | */ | ||||
| bool getNextEvent (MidiMessage& result, | bool getNextEvent (MidiMessage& result, | ||||
| int& samplePosition); | |||||
| int& samplePosition) throw(); | |||||
| /** Retrieves the next event from the buffer. | /** Retrieves the next event from the buffer. | ||||
| @@ -202,7 +202,7 @@ public: | |||||
| */ | */ | ||||
| bool getNextEvent (const uint8* &midiData, | bool getNextEvent (const uint8* &midiData, | ||||
| int& numBytesOfMidiData, | int& numBytesOfMidiData, | ||||
| int& samplePosition); | |||||
| int& samplePosition) throw(); | |||||
| //============================================================================== | //============================================================================== | ||||
| juce_UseDebuggingNewOperator | juce_UseDebuggingNewOperator | ||||
| @@ -223,7 +223,7 @@ private: | |||||
| friend class MidiBuffer::Iterator; | friend class MidiBuffer::Iterator; | ||||
| int bytesUsed; | 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); | memcpy (data, d, dataSize); | ||||
| // check that the length matches the data.. | // 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, | MidiMessage::MidiMessage (const int byte1, | ||||
| @@ -473,6 +473,7 @@ const MidiMessage MidiMessage::controllerEvent (const int channel, | |||||
| const int controllerType, | const int controllerType, | ||||
| const int value) throw() | const int value) throw() | ||||
| { | { | ||||
| // the channel must be between 1 and 16 inclusive | |||||
| jassert (channel > 0 && channel <= 16); | jassert (channel > 0 && channel <= 16); | ||||
| return MidiMessage (0xb0 | jlimit (0, 15, channel - 1), | return MidiMessage (0xb0 | jlimit (0, 15, channel - 1), | ||||