Browse Source

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.

tags/2021-05-28
jules 16 years ago
parent
commit
e6dd20444e
9 changed files with 95 additions and 41 deletions
  1. +14
    -3
      extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm
  2. +17
    -17
      juce_amalgamated.cpp
  3. +27
    -2
      juce_amalgamated.h
  4. +2
    -2
      src/juce_appframework/audio/devices/juce_MidiOutput.cpp
  5. +0
    -9
      src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.cpp
  6. +18
    -2
      src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.h
  7. +7
    -0
      src/juce_appframework/audio/midi/juce_MidiBuffer.cpp
  8. +8
    -0
      src/juce_appframework/audio/midi/juce_MidiBuffer.h
  9. +2
    -6
      src/juce_core/io/network/juce_URL.cpp

+ 14
- 3
extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm View File

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


+ 17
- 17
juce_amalgamated.cpp View File

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


+ 27
- 2
juce_amalgamated.h View File

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




+ 2
- 2
src/juce_appframework/audio/devices/juce_MidiOutput.cpp 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! // 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);


+ 0
- 9
src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.cpp View File

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


+ 18
- 2
src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.h View File

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


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

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


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

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


+ 2
- 6
src/juce_core/io/network/juce_URL.cpp View File

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


Loading…
Cancel
Save