1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Converted AudioSampleBuffer into a templated class that can use either float or double types. Used this to implement 64-bit audio plugin support in VST and AU

This commit is contained in:
jules 2015-11-02 11:09:41 +00:00
parent ba672f03fb
commit c562cfc3cc
27 changed files with 1713 additions and 1104 deletions

View file

@ -71,6 +71,18 @@ bool SynthesiserVoice::wasStartedBefore (const SynthesiserVoice& other) const no
return noteOnTime < other.noteOnTime;
}
void SynthesiserVoice::renderNextBlock (AudioBuffer<double>& outputBuffer,
int startSample, int numSamples)
{
AudioBuffer<double> subBuffer (outputBuffer.getArrayOfWritePointers(),
outputBuffer.getNumChannels(),
startSample, numSamples);
tempBuffer.makeCopyOf (subBuffer);
renderNextBlock (tempBuffer, 0, numSamples);
subBuffer.makeCopyOf (tempBuffer);
}
//==============================================================================
Synthesiser::Synthesiser()
: sampleRate (0),
@ -156,8 +168,11 @@ void Synthesiser::setCurrentPlaybackSampleRate (const double newRate)
}
}
void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBuffer& midiData,
int startSample, int numSamples)
template <typename floatType>
void Synthesiser::processNextBlock (AudioBuffer<floatType>& outputAudio,
const MidiBuffer& midiData,
int startSample,
int numSamples)
{
// must set the sample rate before using this!
jassert (sampleRate != 0);
@ -174,7 +189,7 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
{
if (! midiIterator.getNextEvent (m, midiEventPos))
{
renderVoices (outputBuffer, startSample, numSamples);
renderVoices (outputAudio, startSample, numSamples);
return;
}
@ -182,7 +197,7 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
if (samplesToNextMidiMessage >= numSamples)
{
renderVoices (outputBuffer, startSample, numSamples);
renderVoices (outputAudio, startSample, numSamples);
handleMidiEvent (m);
break;
}
@ -193,7 +208,7 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
continue;
}
renderVoices (outputBuffer, startSample, samplesToNextMidiMessage);
renderVoices (outputAudio, startSample, samplesToNextMidiMessage);
handleMidiEvent (m);
startSample += samplesToNextMidiMessage;
numSamples -= samplesToNextMidiMessage;
@ -203,7 +218,23 @@ void Synthesiser::renderNextBlock (AudioSampleBuffer& outputBuffer, const MidiBu
handleMidiEvent (m);
}
void Synthesiser::renderVoices (AudioSampleBuffer& buffer, int startSample, int numSamples)
// explicit template instantiation
template void Synthesiser::processNextBlock<float> (AudioBuffer<float>& outputAudio,
const MidiBuffer& midiData,
int startSample,
int numSamples);
template void Synthesiser::processNextBlock<double> (AudioBuffer<double>& outputAudio,
const MidiBuffer& midiData,
int startSample,
int numSamples);
void Synthesiser::renderVoices (AudioBuffer<float>& buffer, int startSample, int numSamples)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);
}
void Synthesiser::renderVoices (AudioBuffer<double>& buffer, int startSample, int numSamples)
{
for (int i = voices.size(); --i >= 0;)
voices.getUnchecked (i)->renderNextBlock (buffer, startSample, numSamples);

View file

@ -182,9 +182,12 @@ public:
involve rendering as little as 1 sample at a time. In between rendering callbacks,
the voice's methods will be called to tell it about note and controller events.
*/
virtual void renderNextBlock (AudioSampleBuffer& outputBuffer,
virtual void renderNextBlock (AudioBuffer<float>& outputBuffer,
int startSample,
int numSamples) = 0;
virtual void renderNextBlock (AudioBuffer<double>& outputBuffer,
int startSample,
int numSamples);
/** Changes the voice's reference sample rate.
@ -255,6 +258,8 @@ private:
SynthesiserSound::Ptr currentlyPlayingSound;
bool keyIsDown, sustainPedalDown, sostenutoPedalDown;
AudioBuffer<float> tempBuffer;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// Note the new parameters for this method.
virtual int stopNote (bool) { return 0; }
@ -504,10 +509,17 @@ public:
both to the audio output buffer and the midi input buffer, so any midi events
with timestamps outside the specified region will be ignored.
*/
void renderNextBlock (AudioSampleBuffer& outputAudio,
inline void renderNextBlock (AudioBuffer<float>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples);
int numSamples)
{ processNextBlock (outputAudio, inputMidi, startSample, numSamples); }
inline void renderNextBlock (AudioBuffer<double>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples)
{ processNextBlock (outputAudio, inputMidi, startSample, numSamples); }
/** Returns the current target sample rate at which rendering is being done.
Subclasses may need to know this so that they can pitch things correctly.
@ -545,7 +557,9 @@ protected:
By default this just calls renderNextBlock() on each voice, but you may need
to override it to handle custom cases.
*/
virtual void renderVoices (AudioSampleBuffer& outputAudio,
virtual void renderVoices (AudioBuffer<float>& outputAudio,
int startSample, int numSamples);
virtual void renderVoices (AudioBuffer<double>& outputAudio,
int startSample, int numSamples);
/** Searches through the voices to find one that's not currently playing, and
@ -592,6 +606,12 @@ protected:
private:
//==============================================================================
template <typename floatType>
void processNextBlock (AudioBuffer<floatType>& outputAudio,
const MidiBuffer& inputMidi,
int startSample,
int numSamples);
//==============================================================================
double sampleRate;
uint32 lastNoteOnCounter;
int minimumSubBlockSize;