1
0
Fork 0
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:
jules 2009-05-13 12:08:58 +00:00
parent 0d3f72cbb0
commit e6dd20444e
9 changed files with 95 additions and 41 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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