Browse Source

tags/2021-05-28
jules 18 years ago
parent
commit
ad1c2b740b
12 changed files with 292 additions and 55 deletions
  1. +6
    -0
      build/linux/JUCE.make
  2. +0
    -5
      build/linux/platform_specific_code/juce_linux_Midi.cpp
  3. +4
    -0
      build/macosx/Juce.xcodeproj/project.pbxproj
  4. +0
    -4
      build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp
  5. +0
    -4
      build/win32/platform_specific_code/juce_win32_Midi.cpp
  6. +4
    -0
      build/win32/vc8/JUCE.vcproj
  7. +1
    -0
      docs/JUCE changelist.txt
  8. +178
    -0
      src/juce_appframework/audio/devices/juce_MidiOutput.cpp
  9. +58
    -2
      src/juce_appframework/audio/devices/juce_MidiOutput.h
  10. +20
    -20
      src/juce_appframework/audio/midi/juce_MidiBuffer.cpp
  11. +19
    -19
      src/juce_appframework/audio/midi/juce_MidiBuffer.h
  12. +2
    -1
      src/juce_appframework/audio/midi/juce_MidiMessage.cpp

+ 6
- 0
build/linux/JUCE.make View File

@@ -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 $<)


+ 0
- 5
build/linux/platform_specific_code/juce_linux_Midi.cpp View File

@@ -264,11 +264,6 @@ MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
return newDevice;
}
MidiOutput::MidiOutput()
: internal (0)
{
}
MidiOutput::~MidiOutput()
{
MidiOutputDevice* const device = (MidiOutputDevice*) internal;


+ 4
- 0
build/macosx/Juce.xcodeproj/project.pbxproj View File

@@ -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;
};


+ 0
- 4
build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp View File

@@ -285,10 +285,6 @@ MidiOutput* MidiOutput::openDevice (int index)
return mo;
}
MidiOutput::MidiOutput()
{
}
MidiOutput::~MidiOutput()
{
MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;


+ 0
- 4
build/win32/platform_specific_code/juce_win32_Midi.cpp View File

@@ -551,10 +551,6 @@ MidiOutput* MidiOutput::openDevice (int index)
return 0;
}
MidiOutput::MidiOutput()
{
}
MidiOutput::~MidiOutput()
{
MidiOutHandle* const h = (MidiOutHandle*) internal;


+ 4
- 0
build/win32/vc8/JUCE.vcproj View File

@@ -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"
>


+ 1
- 0
docs/JUCE changelist.txt View File

@@ -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


+ 178
- 0
src/juce_appframework/audio/devices/juce_MidiOutput.cpp View File

@@ -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

+ 58
- 2
src/juce_appframework/audio/devices/juce_MidiOutput.h View File

@@ -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();
};


+ 20
- 20
src/juce_appframework/audio/midi/juce_MidiBuffer.cpp View File

@@ -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;


+ 19
- 19
src/juce_appframework/audio/midi/juce_MidiBuffer.h View File

@@ -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();
};


+ 2
- 1
src/juce_appframework/audio/midi/juce_MidiMessage.cpp View File

@@ -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),


Loading…
Cancel
Save