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


+ 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);
}

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


+ 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);
/** 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.



+ 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!
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);


+ 0
- 9
src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.cpp 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,


+ 18
- 2
src/juce_appframework/audio/dsp/juce_AudioSampleBuffer.h 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.


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


+ 8
- 0
src/juce_appframework/audio/midi/juce_MidiBuffer.h 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.


+ 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++;
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…
Cancel
Save