@@ -557,6 +557,7 @@ public: | |||||
bufferSpace.setSize (2, 16); | bufferSpace.setSize (2, 16); | ||||
midiEvents.clear(); | midiEvents.clear(); | ||||
incomingEvents.clear(); | |||||
prepared = false; | prepared = false; | ||||
} | } | ||||
@@ -591,6 +592,7 @@ public: | |||||
GetMaxFramesPerSlice()); | GetMaxFramesPerSlice()); | ||||
midiEvents.clear(); | midiEvents.clear(); | ||||
incomingEvents.clear(); | |||||
juce_free (channels); | juce_free (channels); | ||||
channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(), | channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(), | ||||
@@ -699,6 +701,12 @@ public: | |||||
break; | break; | ||||
} | } | ||||
{ | |||||
const ScopedLock sl (incomingMidiLock); | |||||
midiEvents.clear(); | |||||
incomingEvents.swap (midiEvents); | |||||
} | |||||
{ | { | ||||
AudioSampleBuffer buffer (channels, jmax (numIn, numOut), numSamples); | AudioSampleBuffer buffer (channels, jmax (numIn, numOut), numSamples); | ||||
@@ -784,12 +792,13 @@ protected: | |||||
#endif | #endif | ||||
{ | { | ||||
#if JucePlugin_WantsMidiInput | #if JucePlugin_WantsMidiInput | ||||
const ScopedLock sl (incomingMidiLock); | |||||
JUCE_NAMESPACE::uint8 data [4]; | JUCE_NAMESPACE::uint8 data [4]; | ||||
data[0] = nStatus | inChannel; | data[0] = nStatus | inChannel; | ||||
data[1] = inData1; | data[1] = inData1; | ||||
data[2] = inData2; | data[2] = inData2; | ||||
midiEvents.addEvent (data, 3, inStartFrame); | |||||
incomingEvents.addEvent (data, 3, inStartFrame); | |||||
#endif | #endif | ||||
return noErr; | return noErr; | ||||
@@ -798,7 +807,8 @@ protected: | |||||
OSStatus HandleSysEx (const UInt8* inData, UInt32 inLength) | OSStatus HandleSysEx (const UInt8* inData, UInt32 inLength) | ||||
{ | { | ||||
#if JucePlugin_WantsMidiInput | #if JucePlugin_WantsMidiInput | ||||
midiEvents.addEvent (inData, inLength, 0); | |||||
const ScopedLock sl (incomingMidiLock); | |||||
incomingEvents.addEvent (inData, inLength, 0); | |||||
#endif | #endif | ||||
return noErr; | return noErr; | ||||
} | } | ||||
@@ -866,12 +876,13 @@ private: | |||||
AudioProcessor* juceFilter; | AudioProcessor* juceFilter; | ||||
AudioSampleBuffer bufferSpace; | AudioSampleBuffer bufferSpace; | ||||
float** channels; | float** channels; | ||||
MidiBuffer midiEvents; | |||||
MidiBuffer midiEvents, incomingEvents; | |||||
bool prepared; | bool prepared; | ||||
SMPTETime lastSMPTETime; | SMPTETime lastSMPTETime; | ||||
AUChannelInfo channelInfo [numChannelConfigs]; | AUChannelInfo channelInfo [numChannelConfigs]; | ||||
AudioUnitEvent auEvent; | AudioUnitEvent auEvent; | ||||
mutable MemoryBlock presetsArray; | mutable MemoryBlock presetsArray; | ||||
CriticalSection incomingMidiLock; | |||||
}; | }; | ||||
//============================================================================== | //============================================================================== | ||||
@@ -3785,6 +3785,12 @@ const var var::call (const var::identifier& method, const var& arg1, const var& | |||||
return invoke (method, args, 4); | return invoke (method, args, 4); | ||||
} | } | ||||
const var var::call (const var::identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const | |||||
{ | |||||
var args[] = { arg1, arg2, arg3, arg4, arg5 }; | |||||
return invoke (method, args, 5); | |||||
} | |||||
var::identifier::identifier (const String& name_) throw() | var::identifier::identifier (const String& name_) throw() | ||||
: name (name_), | : name (name_), | ||||
hashCode (name_.hashCode()) | hashCode (name_.hashCode()) | ||||
@@ -8265,12 +8271,8 @@ const String URL::addEscapeChars (const String& s, const bool isParameter) | |||||
{ | { | ||||
const char c = *utf8++; | const char c = *utf8++; | ||||
if (c == ' ') | |||||
{ | |||||
result += T('+'); | |||||
} | |||||
else if (CharacterFunctions::isLetterOrDigit (c) | |||||
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0) | |||||
if (CharacterFunctions::isLetterOrDigit (c) | |||||
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0) | |||||
{ | { | ||||
result << c; | result << c; | ||||
} | } | ||||
@@ -23472,7 +23474,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, | |||||
// this needs to be a value in the future - RTFM for this method! | // this needs to be a value in the future - RTFM for this method! | ||||
jassert (millisecondCounterToStartAt > 0); | jassert (millisecondCounterToStartAt > 0); | ||||
samplesPerSecondForBuffer *= 0.001; | |||||
const double timeScaleFactor = 1000.0 / samplesPerSecondForBuffer; | |||||
MidiBuffer::Iterator i (buffer); | MidiBuffer::Iterator i (buffer); | ||||
@@ -23481,7 +23483,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, | |||||
while (i.getNextEvent (data, len, time)) | while (i.getNextEvent (data, len, time)) | ||||
{ | { | ||||
const double eventTime = millisecondCounterToStartAt + samplesPerSecondForBuffer * time; | |||||
const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time; | |||||
PendingMessage* const m | PendingMessage* const m | ||||
= new PendingMessage (data, len, eventTime); | = new PendingMessage (data, len, eventTime); | ||||
@@ -24223,15 +24225,6 @@ AudioSampleBuffer::~AudioSampleBuffer() throw() | |||||
juce_free (channels); | juce_free (channels); | ||||
} | } | ||||
float* AudioSampleBuffer::getSampleData (const int channelNumber, | |||||
const int sampleOffset) const throw() | |||||
{ | |||||
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); | |||||
jassert (((unsigned int) sampleOffset) < (unsigned int) size); | |||||
return channels [channelNumber] + sampleOffset; | |||||
} | |||||
void AudioSampleBuffer::setSize (const int newNumChannels, | void AudioSampleBuffer::setSize (const int newNumChannels, | ||||
const int newNumSamples, | const int newNumSamples, | ||||
const bool keepExistingContent, | const bool keepExistingContent, | ||||
@@ -25053,6 +25046,13 @@ const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw() | |||||
return *this; | return *this; | ||||
} | } | ||||
void MidiBuffer::swap (MidiBuffer& other) | |||||
{ | |||||
swapVariables <uint8*> (this->elements, other.elements); | |||||
swapVariables <int> (this->numAllocated, other.numAllocated); | |||||
swapVariables <int> (this->bytesUsed, other.bytesUsed); | |||||
} | |||||
MidiBuffer::~MidiBuffer() throw() | MidiBuffer::~MidiBuffer() throw() | ||||
{ | { | ||||
} | } | ||||
@@ -11454,6 +11454,8 @@ public: | |||||
const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3); | const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3); | ||||
/** If this variant is an object, this invokes one of its methods with 4 arguments. */ | /** If this variant is an object, this invokes one of its methods with 4 arguments. */ | ||||
const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; | const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; | ||||
/** If this variant is an object, this invokes one of its methods with 5 arguments. */ | |||||
const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; | |||||
/** If this variant is an object, this invokes one of its methods with a list of arguments. */ | /** If this variant is an object, this invokes one of its methods with a list of arguments. */ | ||||
const var invoke (const identifier& method, const var* arguments, int numArguments) const; | const var invoke (const identifier& method, const var* arguments, int numArguments) const; | ||||
@@ -26057,6 +26059,13 @@ public: | |||||
*/ | */ | ||||
int getLastEventTime() const throw(); | int getLastEventTime() const throw(); | ||||
/** Exchanges the contents of this buffer with another one. | |||||
This is a quick operation, because no memory allocating or copying is done, it | |||||
just swaps the internal state of the two buffers. | |||||
*/ | |||||
void swap (MidiBuffer& other); | |||||
/** | /** | ||||
Used to iterate through the events in a MidiBuffer. | Used to iterate through the events in a MidiBuffer. | ||||
@@ -27110,13 +27119,29 @@ public: | |||||
*/ | */ | ||||
int getNumSamples() const throw() { return size; } | int getNumSamples() const throw() { return size; } | ||||
/** Returns a pointer one of the buffer's channels. | |||||
For speed, this doesn't check whether the channel number is out of range, | |||||
so be careful when using it! | |||||
*/ | |||||
float* getSampleData (const int channelNumber) const throw() | |||||
{ | |||||
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); | |||||
return channels [channelNumber]; | |||||
} | |||||
/** Returns a pointer to a sample in one of the buffer's channels. | /** Returns a pointer to a sample in one of the buffer's channels. | ||||
For speed, this doesn't check whether the channel and sample number | For speed, this doesn't check whether the channel and sample number | ||||
are legal, so be careful when using it! | |||||
are out-of-range, so be careful when using it! | |||||
*/ | */ | ||||
float* getSampleData (const int channelNumber, | float* getSampleData (const int channelNumber, | ||||
const int sampleOffset = 0) const throw(); | |||||
const int sampleOffset) const throw() | |||||
{ | |||||
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); | |||||
jassert (((unsigned int) sampleOffset) < (unsigned int) size); | |||||
return channels [channelNumber] + sampleOffset; | |||||
} | |||||
/** Returns an array of pointers to the channels in the buffer. | /** Returns an array of pointers to the channels in the buffer. | ||||
@@ -63,7 +63,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, | |||||
// this needs to be a value in the future - RTFM for this method! | // this needs to be a value in the future - RTFM for this method! | ||||
jassert (millisecondCounterToStartAt > 0); | jassert (millisecondCounterToStartAt > 0); | ||||
samplesPerSecondForBuffer *= 0.001; | |||||
const double timeScaleFactor = 1000.0 / samplesPerSecondForBuffer; | |||||
MidiBuffer::Iterator i (buffer); | MidiBuffer::Iterator i (buffer); | ||||
@@ -72,7 +72,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer, | |||||
while (i.getNextEvent (data, len, time)) | while (i.getNextEvent (data, len, time)) | ||||
{ | { | ||||
const double eventTime = millisecondCounterToStartAt + samplesPerSecondForBuffer * time; | |||||
const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time; | |||||
PendingMessage* const m | PendingMessage* const m | ||||
= new PendingMessage (data, len, eventTime); | = new PendingMessage (data, len, eventTime); | ||||
@@ -169,15 +169,6 @@ AudioSampleBuffer::~AudioSampleBuffer() throw() | |||||
juce_free (channels); | juce_free (channels); | ||||
} | } | ||||
float* AudioSampleBuffer::getSampleData (const int channelNumber, | |||||
const int sampleOffset) const throw() | |||||
{ | |||||
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); | |||||
jassert (((unsigned int) sampleOffset) < (unsigned int) size); | |||||
return channels [channelNumber] + sampleOffset; | |||||
} | |||||
void AudioSampleBuffer::setSize (const int newNumChannels, | void AudioSampleBuffer::setSize (const int newNumChannels, | ||||
const int newNumSamples, | const int newNumSamples, | ||||
const bool keepExistingContent, | const bool keepExistingContent, | ||||
@@ -108,13 +108,29 @@ public: | |||||
*/ | */ | ||||
int getNumSamples() const throw() { return size; } | int getNumSamples() const throw() { return size; } | ||||
/** Returns a pointer one of the buffer's channels. | |||||
For speed, this doesn't check whether the channel number is out of range, | |||||
so be careful when using it! | |||||
*/ | |||||
float* getSampleData (const int channelNumber) const throw() | |||||
{ | |||||
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); | |||||
return channels [channelNumber]; | |||||
} | |||||
/** Returns a pointer to a sample in one of the buffer's channels. | /** Returns a pointer to a sample in one of the buffer's channels. | ||||
For speed, this doesn't check whether the channel and sample number | For speed, this doesn't check whether the channel and sample number | ||||
are legal, so be careful when using it! | |||||
are out-of-range, so be careful when using it! | |||||
*/ | */ | ||||
float* getSampleData (const int channelNumber, | float* getSampleData (const int channelNumber, | ||||
const int sampleOffset = 0) const throw(); | |||||
const int sampleOffset) const throw() | |||||
{ | |||||
jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); | |||||
jassert (((unsigned int) sampleOffset) < (unsigned int) size); | |||||
return channels [channelNumber] + sampleOffset; | |||||
} | |||||
/** Returns an array of pointers to the channels in the buffer. | /** Returns an array of pointers to the channels in the buffer. | ||||
@@ -72,6 +72,13 @@ const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw() | |||||
return *this; | return *this; | ||||
} | } | ||||
void MidiBuffer::swap (MidiBuffer& other) | |||||
{ | |||||
swapVariables <uint8*> (this->elements, other.elements); | |||||
swapVariables <int> (this->numAllocated, other.numAllocated); | |||||
swapVariables <int> (this->bytesUsed, other.bytesUsed); | |||||
} | |||||
MidiBuffer::~MidiBuffer() throw() | MidiBuffer::~MidiBuffer() throw() | ||||
{ | { | ||||
} | } | ||||
@@ -155,6 +155,14 @@ public: | |||||
*/ | */ | ||||
int getLastEventTime() const throw(); | int getLastEventTime() const throw(); | ||||
//============================================================================== | |||||
/** Exchanges the contents of this buffer with another one. | |||||
This is a quick operation, because no memory allocating or copying is done, it | |||||
just swaps the internal state of the two buffers. | |||||
*/ | |||||
void swap (MidiBuffer& other); | |||||
//============================================================================== | //============================================================================== | ||||
/** | /** | ||||
Used to iterate through the events in a MidiBuffer. | Used to iterate through the events in a MidiBuffer. | ||||
@@ -525,12 +525,8 @@ const String URL::addEscapeChars (const String& s, const bool isParameter) | |||||
{ | { | ||||
const char c = *utf8++; | const char c = *utf8++; | ||||
if (c == ' ') | |||||
{ | |||||
result += T('+'); | |||||
} | |||||
else if (CharacterFunctions::isLetterOrDigit (c) | |||||
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0) | |||||
if (CharacterFunctions::isLetterOrDigit (c) | |||||
|| CharacterFunctions::indexOfChar (legalChars, c, false) >= 0) | |||||
{ | { | ||||
result << c; | result << c; | ||||
} | } | ||||