Refactor the processes in chunks

This commit is contained in:
Paul Ferrand 2020-03-30 19:13:35 +02:00
parent a337cf5a15
commit eac0c0e804
2 changed files with 147 additions and 130 deletions

View file

@ -240,10 +240,15 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
fillWithData(delayed_buffer); fillWithData(delayed_buffer);
} }
if (region->isStereo) if (region->isStereo) {
processStereo(buffer); ampStageStereo(buffer);
else panStageStereo(buffer);
processMono(buffer); filterStageStereo(buffer);
} else {
ampStageMono(buffer);
filterStageMono(buffer);
panStageMono(buffer);
}
if (!egEnvelope.isSmoothing()) if (!egEnvelope.isSmoothing())
reset(); reset();
@ -252,29 +257,27 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
this->triggerDelay = absl::nullopt; this->triggerDelay = absl::nullopt;
} }
void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept void sfz::Voice::ampStageMono(AudioSpan<float> buffer) noexcept
{ {
ScopedTiming logger { amplitudeDuration };
const auto numSamples = buffer.getNumFrames(); const auto numSamples = buffer.getNumFrames();
auto leftBuffer = buffer.getSpan(0); const auto leftBuffer = buffer.getSpan(0);
auto rightBuffer = buffer.getSpan(1);
using namespace std::placeholders;
const auto xfinBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
const auto xfoutBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
auto modulationSpan = resources.bufferPool.getBuffer(numSamples); auto modulationSpan = resources.bufferPool.getBuffer(numSamples);
auto tempSpan = resources.bufferPool.getBuffer(numSamples); auto tempSpan = resources.bufferPool.getBuffer(numSamples);
if (!modulationSpan || !tempSpan) if (!modulationSpan || !tempSpan)
return; return;
using namespace std::placeholders;
const auto xfinBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
const auto xfoutBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
{ // Amplitude processing
ScopedTiming logger { amplitudeDuration };
// Amplitude envelope // Amplitude envelope
fill<float>(*modulationSpan, baseGain); fill<float>(*modulationSpan, baseGain);
resources.midiState.multiplicativeModifiers(region->amplitudeCC, *modulationSpan, *tempSpan); resources.midiState.multiplicativeModifiers(region->amplitudeCC, *modulationSpan, *tempSpan);
DBG("Final gain: " << modulationSpan->back()); DBG("Final gain: " << modulationSpan->back());
applyGain<float>(modulationSpan, leftBuffer); applyGain<float>(*modulationSpan, leftBuffer);
// Crossfade envelopes // Crossfade envelopes
// crossfadeEnvelope.getBlock(modulationSpan); // crossfadeEnvelope.getBlock(modulationSpan);
@ -282,7 +285,7 @@ void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept
resources.midiState.multiplicativeModifiers(region->crossfadeCCInRange, *modulationSpan, *tempSpan, xfinBind); resources.midiState.multiplicativeModifiers(region->crossfadeCCInRange, *modulationSpan, *tempSpan, xfinBind);
resources.midiState.multiplicativeModifiers(region->crossfadeCCOutRange, *modulationSpan, *tempSpan, xfoutBind); resources.midiState.multiplicativeModifiers(region->crossfadeCCOutRange, *modulationSpan, *tempSpan, xfoutBind);
DBG("XF: " << modulationSpan->back()); DBG("XF: " << modulationSpan->back());
applyGain<float>(modulationSpan, leftBuffer); applyGain<float>(*modulationSpan, leftBuffer);
// Volume envelope // Volume envelope
volumeEnvelope.getBlock(*modulationSpan); volumeEnvelope.getBlock(*modulationSpan);
@ -293,23 +296,54 @@ void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept
applyGain<float>(*modulationSpan, leftBuffer); applyGain<float>(*modulationSpan, leftBuffer);
} }
{ // Filtering and EQ void sfz::Voice::ampStageStereo(AudioSpan<float> buffer) noexcept
ScopedTiming logger { filterDuration }; {
ScopedTiming logger { amplitudeDuration };
const float* inputChannel[1] { leftBuffer.data() }; const auto numSamples = buffer.getNumFrames();
float* outputChannel[1] { leftBuffer.data() };
for (auto& filter: filters) { auto modulationSpan = resources.bufferPool.getBuffer(numSamples);
filter->process(inputChannel, outputChannel, numSamples); auto tempSpan = resources.bufferPool.getBuffer(numSamples);
if (!modulationSpan || !tempSpan)
return;
using namespace std::placeholders;
const auto xfinBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
const auto xfoutBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
// Amplitude envelope
fill<float>(*modulationSpan, baseGain);
resources.midiState.multiplicativeModifiers(region->amplitudeCC, *modulationSpan, *tempSpan);
buffer.applyGain(*modulationSpan);
// Crossfade envelopes
fill<float>(*modulationSpan, 1.0f);
resources.midiState.multiplicativeModifiers(region->crossfadeCCInRange, *modulationSpan, *tempSpan, xfinBind);
resources.midiState.multiplicativeModifiers(region->crossfadeCCOutRange, *modulationSpan, *tempSpan, xfoutBind);
buffer.applyGain(*modulationSpan);
// Volume envelope
volumeEnvelope.getBlock(*modulationSpan);
buffer.applyGain(*modulationSpan);
// AmpEG envelope
egEnvelope.getBlock(*modulationSpan);
buffer.applyGain(*modulationSpan);
} }
for (auto& eq: equalizers) { void sfz::Voice::panStageMono(AudioSpan<float> buffer) noexcept
eq->process(inputChannel, outputChannel, numSamples); {
}
}
{ // Panning and stereo processing
ScopedTiming logger { panningDuration }; ScopedTiming logger { panningDuration };
const auto numSamples = buffer.getNumFrames();
const auto leftBuffer = buffer.getSpan(0);
const auto rightBuffer = buffer.getSpan(1);
auto modulationSpan = resources.bufferPool.getBuffer(numSamples);
auto tempSpan = resources.bufferPool.getBuffer(numSamples);
if (!modulationSpan || !tempSpan)
return;
// Prepare for stereo output // Prepare for stereo output
copy<float>(leftBuffer, rightBuffer); copy<float>(leftBuffer, rightBuffer);
@ -319,49 +353,19 @@ void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept
DBG("Pan: " << modulationSpan->back()); DBG("Pan: " << modulationSpan->back());
pan<float>(*modulationSpan, leftBuffer, rightBuffer); pan<float>(*modulationSpan, leftBuffer, rightBuffer);
} }
}
void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
{ {
ScopedTiming logger { panningDuration };
const auto numSamples = buffer.getNumFrames(); const auto numSamples = buffer.getNumFrames();
auto leftBuffer = buffer.getSpan(0); const auto leftBuffer = buffer.getSpan(0);
auto rightBuffer = buffer.getSpan(1); const auto rightBuffer = buffer.getSpan(1);
auto modulationSpan = resources.bufferPool.getBuffer(numSamples); auto modulationSpan = resources.bufferPool.getBuffer(numSamples);
auto tempSpan = resources.bufferPool.getBuffer(numSamples); auto tempSpan = resources.bufferPool.getBuffer(numSamples);
if (!modulationSpan || !tempSpan) if (!modulationSpan || !tempSpan)
return; return;
using namespace std::placeholders;
const auto xfinBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
const auto xfoutBind = std::bind(crossfadeIn<float, float>, _1, _2, region->crossfadeCCCurve);
{ // Amplitude processing
ScopedTiming logger { amplitudeDuration };
// Amplitude envelope
fill<float>(*modulationSpan, baseGain);
resources.midiState.multiplicativeModifiers(region->amplitudeCC, *modulationSpan, *tempSpan);
buffer.applyGain(*modulationSpan);
// Crossfade envelopes
fill<float>(*modulationSpan, 1.0f);
resources.midiState.multiplicativeModifiers(region->crossfadeCCInRange, *modulationSpan, *tempSpan, xfinBind);
resources.midiState.multiplicativeModifiers(region->crossfadeCCOutRange, *modulationSpan, *tempSpan, xfoutBind);
buffer.applyGain(*modulationSpan);
// Volume envelope
volumeEnvelope.getBlock(*modulationSpan);
buffer.applyGain(*modulationSpan);
// AmpEG envelope
egEnvelope.getBlock(*modulationSpan);
buffer.applyGain(*modulationSpan);
}
{ // Panning and stereo processing
ScopedTiming logger { panningDuration };
// Apply panning // Apply panning
// panningModulation(*modulationSpan); // panningModulation(*modulationSpan);
fill<float>(*modulationSpan, region->pan); fill<float>(*modulationSpan, region->pan);
@ -380,8 +384,28 @@ void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
pan<float>(*modulationSpan, leftBuffer, rightBuffer); pan<float>(*modulationSpan, leftBuffer, rightBuffer);
} }
{ // Filtering and EQ void sfz::Voice::filterStageMono(AudioSpan<float> buffer) noexcept
{
ScopedTiming logger { filterDuration }; ScopedTiming logger { filterDuration };
const auto numSamples = buffer.getNumFrames();
const auto leftBuffer = buffer.getSpan(0);
const float* inputChannel[1] { leftBuffer.data() };
float* outputChannel[1] { leftBuffer.data() };
for (auto& filter: filters) {
filter->process(inputChannel, outputChannel, numSamples);
}
for (auto& eq: equalizers) {
eq->process(inputChannel, outputChannel, numSamples);
}
}
void sfz::Voice::filterStageStereo(AudioSpan<float> buffer) noexcept
{
ScopedTiming logger { filterDuration };
const auto numSamples = buffer.getNumFrames();
const auto leftBuffer = buffer.getSpan(0);
const auto rightBuffer = buffer.getSpan(1);
const float* inputChannels[2] { leftBuffer.data(), rightBuffer.data() }; const float* inputChannels[2] { leftBuffer.data(), rightBuffer.data() };
float* outputChannels[2] { leftBuffer.data(), rightBuffer.data() }; float* outputChannels[2] { leftBuffer.data(), rightBuffer.data() };
@ -394,7 +418,6 @@ void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
eq->process(inputChannels, outputChannels, numSamples); eq->process(inputChannels, outputChannels, numSamples);
} }
} }
}
void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept void sfz::Voice::fillWithData(AudioSpan<float> buffer) noexcept
{ {

View file

@ -238,18 +238,12 @@ private:
* @param buffer * @param buffer
*/ */
void fillWithGenerator(AudioSpan<float> buffer) noexcept; void fillWithGenerator(AudioSpan<float> buffer) noexcept;
/** void ampStageMono(AudioSpan<float> buffer) noexcept;
* @brief The function processing a mono sample source void ampStageStereo(AudioSpan<float> buffer) noexcept;
* void panStageMono(AudioSpan<float> buffer) noexcept;
* @param buffer void panStageStereo(AudioSpan<float> buffer) noexcept;
*/ void filterStageMono(AudioSpan<float> buffer) noexcept;
void processMono(AudioSpan<float> buffer) noexcept; void filterStageStereo(AudioSpan<float> buffer) noexcept;
/**
* @brief The function processing a stereo sample source
*
* @param buffer
*/
void processStereo(AudioSpan<float> buffer) noexcept;
Region* region { nullptr }; Region* region { nullptr };