mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-21 01:24:21 +00:00
Fix for AU plugin midi event threading on some hosts; fix for timing of MidiOutput::sendBlockOfMessages; Fix for URL::addEscapeChars; added a MidiBuffer::swap method; restructured some AudioSampleBuffer methods to aid compiler inlining.
This commit is contained in:
parent
0d3f72cbb0
commit
e6dd20444e
9 changed files with 95 additions and 41 deletions
|
|
@ -557,6 +557,7 @@ public:
|
|||
|
||||
bufferSpace.setSize (2, 16);
|
||||
midiEvents.clear();
|
||||
incomingEvents.clear();
|
||||
prepared = false;
|
||||
}
|
||||
|
||||
|
|
@ -591,6 +592,7 @@ public:
|
|||
GetMaxFramesPerSlice());
|
||||
|
||||
midiEvents.clear();
|
||||
incomingEvents.clear();
|
||||
|
||||
juce_free (channels);
|
||||
channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(),
|
||||
|
|
@ -699,6 +701,12 @@ public:
|
|||
break;
|
||||
}
|
||||
|
||||
{
|
||||
const ScopedLock sl (incomingMidiLock);
|
||||
midiEvents.clear();
|
||||
incomingEvents.swap (midiEvents);
|
||||
}
|
||||
|
||||
{
|
||||
AudioSampleBuffer buffer (channels, jmax (numIn, numOut), numSamples);
|
||||
|
||||
|
|
@ -784,12 +792,13 @@ protected:
|
|||
#endif
|
||||
{
|
||||
#if JucePlugin_WantsMidiInput
|
||||
const ScopedLock sl (incomingMidiLock);
|
||||
JUCE_NAMESPACE::uint8 data [4];
|
||||
data[0] = nStatus | inChannel;
|
||||
data[1] = inData1;
|
||||
data[2] = inData2;
|
||||
|
||||
midiEvents.addEvent (data, 3, inStartFrame);
|
||||
incomingEvents.addEvent (data, 3, inStartFrame);
|
||||
#endif
|
||||
|
||||
return noErr;
|
||||
|
|
@ -798,7 +807,8 @@ protected:
|
|||
OSStatus HandleSysEx (const UInt8* inData, UInt32 inLength)
|
||||
{
|
||||
#if JucePlugin_WantsMidiInput
|
||||
midiEvents.addEvent (inData, inLength, 0);
|
||||
const ScopedLock sl (incomingMidiLock);
|
||||
incomingEvents.addEvent (inData, inLength, 0);
|
||||
#endif
|
||||
return noErr;
|
||||
}
|
||||
|
|
@ -866,12 +876,13 @@ private:
|
|||
AudioProcessor* juceFilter;
|
||||
AudioSampleBuffer bufferSpace;
|
||||
float** channels;
|
||||
MidiBuffer midiEvents;
|
||||
MidiBuffer midiEvents, incomingEvents;
|
||||
bool prepared;
|
||||
SMPTETime lastSMPTETime;
|
||||
AUChannelInfo channelInfo [numChannelConfigs];
|
||||
AudioUnitEvent auEvent;
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
: name (name_),
|
||||
hashCode (name_.hashCode())
|
||||
|
|
@ -8265,12 +8271,8 @@ const String URL::addEscapeChars (const String& s, const bool isParameter)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
@ -23472,7 +23474,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer,
|
|||
// this needs to be a value in the future - RTFM for this method!
|
||||
jassert (millisecondCounterToStartAt > 0);
|
||||
|
||||
samplesPerSecondForBuffer *= 0.001;
|
||||
const double timeScaleFactor = 1000.0 / samplesPerSecondForBuffer;
|
||||
|
||||
MidiBuffer::Iterator i (buffer);
|
||||
|
||||
|
|
@ -23481,7 +23483,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer,
|
|||
|
||||
while (i.getNextEvent (data, len, time))
|
||||
{
|
||||
const double eventTime = millisecondCounterToStartAt + samplesPerSecondForBuffer * time;
|
||||
const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time;
|
||||
|
||||
PendingMessage* const m
|
||||
= new PendingMessage (data, len, eventTime);
|
||||
|
|
@ -24223,15 +24225,6 @@ AudioSampleBuffer::~AudioSampleBuffer() throw()
|
|||
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,
|
||||
const int newNumSamples,
|
||||
const bool keepExistingContent,
|
||||
|
|
@ -25053,6 +25046,13 @@ const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw()
|
|||
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()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11454,6 +11454,8 @@ public:
|
|||
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. */
|
||||
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. */
|
||||
const var invoke (const identifier& method, const var* arguments, int numArguments) const;
|
||||
|
|
@ -26057,6 +26059,13 @@ public:
|
|||
*/
|
||||
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.
|
||||
|
||||
|
|
@ -27110,13 +27119,29 @@ public:
|
|||
*/
|
||||
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.
|
||||
|
||||
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,
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer,
|
|||
// this needs to be a value in the future - RTFM for this method!
|
||||
jassert (millisecondCounterToStartAt > 0);
|
||||
|
||||
samplesPerSecondForBuffer *= 0.001;
|
||||
const double timeScaleFactor = 1000.0 / samplesPerSecondForBuffer;
|
||||
|
||||
MidiBuffer::Iterator i (buffer);
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ void MidiOutput::sendBlockOfMessages (const MidiBuffer& buffer,
|
|||
|
||||
while (i.getNextEvent (data, len, time))
|
||||
{
|
||||
const double eventTime = millisecondCounterToStartAt + samplesPerSecondForBuffer * time;
|
||||
const double eventTime = millisecondCounterToStartAt + timeScaleFactor * time;
|
||||
|
||||
PendingMessage* const m
|
||||
= new PendingMessage (data, len, eventTime);
|
||||
|
|
|
|||
|
|
@ -169,15 +169,6 @@ AudioSampleBuffer::~AudioSampleBuffer() throw()
|
|||
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,
|
||||
const int newNumSamples,
|
||||
const bool keepExistingContent,
|
||||
|
|
|
|||
|
|
@ -108,13 +108,29 @@ public:
|
|||
*/
|
||||
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.
|
||||
|
||||
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,
|
||||
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.
|
||||
|
||||
|
|
|
|||
|
|
@ -72,6 +72,13 @@ const MidiBuffer& MidiBuffer::operator= (const MidiBuffer& other) throw()
|
|||
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()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,6 +155,14 @@ public:
|
|||
*/
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -525,12 +525,8 @@ const String URL::addEscapeChars (const String& s, const bool isParameter)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue