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);
}
if (region->isStereo)
processStereo(buffer);
else
processMono(buffer);
if (region->isStereo) {
ampStageStereo(buffer);
panStageStereo(buffer);
filterStageStereo(buffer);
} else {
ampStageMono(buffer);
filterStageMono(buffer);
panStageMono(buffer);
}
if (!egEnvelope.isSmoothing())
reset();
@ -252,11 +257,50 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
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 leftBuffer = buffer.getSpan(0);
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 tempSpan = resources.bufferPool.getBuffer(numSamples);
if (!modulationSpan || !tempSpan)
return;
// Amplitude envelope
fill<float>(*modulationSpan, baseGain);
resources.midiState.multiplicativeModifiers(region->amplitudeCC, *modulationSpan, *tempSpan);
DBG("Final gain: " << modulationSpan->back());
applyGain<float>(*modulationSpan, leftBuffer);
// Crossfade envelopes
// crossfadeEnvelope.getBlock(modulationSpan);
fill<float>(*modulationSpan, 1.0f);
resources.midiState.multiplicativeModifiers(region->crossfadeCCInRange, *modulationSpan, *tempSpan, xfinBind);
resources.midiState.multiplicativeModifiers(region->crossfadeCCOutRange, *modulationSpan, *tempSpan, xfoutBind);
DBG("XF: " << modulationSpan->back());
applyGain<float>(*modulationSpan, leftBuffer);
// Volume envelope
volumeEnvelope.getBlock(*modulationSpan);
applyGain<float>(*modulationSpan, leftBuffer);
// AmpEG envelope
egEnvelope.getBlock(*modulationSpan);
applyGain<float>(*modulationSpan, leftBuffer);
}
void sfz::Voice::ampStageStereo(AudioSpan<float> buffer) noexcept
{
ScopedTiming logger { amplitudeDuration };
const auto numSamples = buffer.getNumFrames();
auto leftBuffer = buffer.getSpan(0);
auto rightBuffer = buffer.getSpan(1);
auto modulationSpan = resources.bufferPool.getBuffer(numSamples);
auto tempSpan = resources.bufferPool.getBuffer(numSamples);
@ -267,132 +311,111 @@ void sfz::Voice::processMono(AudioSpan<float> buffer) noexcept
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);
// Amplitude envelope
fill<float>(*modulationSpan, baseGain);
resources.midiState.multiplicativeModifiers(region->amplitudeCC, *modulationSpan, *tempSpan);
DBG("Final gain: " << modulationSpan->back());
applyGain<float>(modulationSpan, leftBuffer);
// 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);
// Crossfade envelopes
// crossfadeEnvelope.getBlock(modulationSpan);
fill<float>(*modulationSpan, 1.0f);
resources.midiState.multiplicativeModifiers(region->crossfadeCCInRange, *modulationSpan, *tempSpan, xfinBind);
resources.midiState.multiplicativeModifiers(region->crossfadeCCOutRange, *modulationSpan, *tempSpan, xfoutBind);
DBG("XF: " << modulationSpan->back());
applyGain<float>(modulationSpan, leftBuffer);
// Volume envelope
volumeEnvelope.getBlock(*modulationSpan);
buffer.applyGain(*modulationSpan);
// Volume envelope
volumeEnvelope.getBlock(*modulationSpan);
applyGain<float>(*modulationSpan, leftBuffer);
// AmpEG envelope
egEnvelope.getBlock(*modulationSpan);
buffer.applyGain(*modulationSpan);
}
// AmpEG envelope
egEnvelope.getBlock(*modulationSpan);
applyGain<float>(*modulationSpan, leftBuffer);
void sfz::Voice::panStageMono(AudioSpan<float> buffer) noexcept
{
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
copy<float>(leftBuffer, rightBuffer);
// Apply panning
fill<float>(*modulationSpan, region->pan);
resources.midiState.additiveModifiers(region->panCC, *modulationSpan, *tempSpan);
DBG("Pan: " << modulationSpan->back());
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
}
void sfz::Voice::panStageStereo(AudioSpan<float> buffer) noexcept
{
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;
// Apply panning
// panningModulation(*modulationSpan);
fill<float>(*modulationSpan, region->pan);
resources.midiState.additiveModifiers(region->panCC, *modulationSpan, *tempSpan);
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
// Apply the width/position process
// widthModulation(*modulationSpan);
fill<float>(*modulationSpan, region->width);
resources.midiState.additiveModifiers(region->widthCC, *modulationSpan, *tempSpan);
width<float>(*modulationSpan, leftBuffer, rightBuffer);
// positionModulation(*modulationSpan);
fill<float>(*modulationSpan, region->position);
resources.midiState.additiveModifiers(region->positionCC, *modulationSpan, *tempSpan);
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
}
void sfz::Voice::filterStageMono(AudioSpan<float> buffer) noexcept
{
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);
}
{ // Filtering and EQ
ScopedTiming logger { filterDuration };
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);
}
}
{ // Panning and stereo processing
ScopedTiming logger { panningDuration };
// Prepare for stereo output
copy<float>(leftBuffer, rightBuffer);
// Apply panning
fill<float>(*modulationSpan, region->pan);
resources.midiState.additiveModifiers(region->panCC, *modulationSpan, *tempSpan);
DBG("Pan: " << modulationSpan->back());
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
for (auto& eq: equalizers) {
eq->process(inputChannel, outputChannel, numSamples);
}
}
void sfz::Voice::processStereo(AudioSpan<float> buffer) noexcept
void sfz::Voice::filterStageStereo(AudioSpan<float> buffer) noexcept
{
ScopedTiming logger { filterDuration };
const auto numSamples = buffer.getNumFrames();
auto leftBuffer = buffer.getSpan(0);
auto rightBuffer = buffer.getSpan(1);
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;
const float* inputChannels[2] { leftBuffer.data(), rightBuffer.data() };
float* outputChannels[2] { leftBuffer.data(), rightBuffer.data() };
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);
for (auto& filter: filters) {
filter->process(inputChannels, outputChannels, numSamples);
}
{ // Panning and stereo processing
ScopedTiming logger { panningDuration };
// Apply panning
// panningModulation(*modulationSpan);
fill<float>(*modulationSpan, region->pan);
resources.midiState.additiveModifiers(region->panCC, *modulationSpan, *tempSpan);
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
// Apply the width/position process
// widthModulation(*modulationSpan);
fill<float>(*modulationSpan, region->width);
resources.midiState.additiveModifiers(region->widthCC, *modulationSpan, *tempSpan);
width<float>(*modulationSpan, leftBuffer, rightBuffer);
// positionModulation(*modulationSpan);
fill<float>(*modulationSpan, region->position);
resources.midiState.additiveModifiers(region->positionCC, *modulationSpan, *tempSpan);
pan<float>(*modulationSpan, leftBuffer, rightBuffer);
}
{ // Filtering and EQ
ScopedTiming logger { filterDuration };
const float* inputChannels[2] { leftBuffer.data(), rightBuffer.data() };
float* outputChannels[2] { leftBuffer.data(), rightBuffer.data() };
for (auto& filter: filters) {
filter->process(inputChannels, outputChannels, numSamples);
}
for (auto& eq: equalizers) {
eq->process(inputChannels, outputChannels, numSamples);
}
for (auto& eq: equalizers) {
eq->process(inputChannels, outputChannels, numSamples);
}
}

View file

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