Ensure to generate sources once only

This commit is contained in:
Jean Pierre Cimalando 2020-08-04 17:31:30 +02:00
parent fb873ad895
commit 094107206a

View file

@ -51,8 +51,6 @@ struct ModMatrix::Impl {
std::vector<Source> sources_; std::vector<Source> sources_;
std::vector<Target> targets_; std::vector<Target> targets_;
Buffer<float> temp_;
}; };
ModMatrix::ModMatrix() ModMatrix::ModMatrix()
@ -104,8 +102,6 @@ void ModMatrix::setSamplesPerBlock(unsigned samplesPerBlock)
} }
for (Impl::Target &target : impl.targets_) for (Impl::Target &target : impl.targets_)
target.buffer.resize(samplesPerBlock); target.buffer.resize(samplesPerBlock);
impl.temp_.resize(samplesPerBlock);
} }
ModMatrix::SourceId ModMatrix::registerSource(const ModKey& key, ModGenerator& gen) ModMatrix::SourceId ModMatrix::registerSource(const ModKey& key, ModGenerator& gen)
@ -315,7 +311,7 @@ float* ModMatrix::getModulation(TargetId targetId)
auto sourcesEnd = target.connectedSources.end(); auto sourcesEnd = target.connectedSources.end();
bool isFirstSource = true; bool isFirstSource = true;
// generate first source in output buffer, next sources in temporary buffer // generate sources in their dedicated buffers
// then add or multiply, depending on target flags // then add or multiply, depending on target flags
while (sourcesPos != sourcesEnd) { while (sourcesPos != sourcesEnd) {
Impl::Source &source = impl.sources_[sourcesPos->first]; Impl::Source &source = impl.sources_[sourcesPos->first];
@ -328,29 +324,37 @@ float* ModMatrix::getModulation(TargetId targetId)
useThisSource = (regionId == source.key.region()); useThisSource = (regionId == source.key.region());
if (useThisSource) { if (useThisSource) {
absl::Span<float> sourceBuffer(source.buffer.data(), numFrames);
// unless source is already done, process it
if (!source.bufferReady) {
source.gen->generate(source.key, impl.currentVoiceId_, sourceBuffer);
source.bufferReady = true;
}
if (isFirstSource) { if (isFirstSource) {
source.gen->generate(source.key, impl.currentVoiceId_, buffer);
if (sourceDepth != 1) { if (sourceDepth != 1) {
for (uint32_t i = 0; i < numFrames; ++i) for (uint32_t i = 0; i < numFrames; ++i)
buffer[i] *= sourceDepth; buffer[i] = sourceDepth * sourceBuffer[i];
}
else {
copy(absl::Span<const float>(sourceBuffer), buffer);
} }
isFirstSource = false; isFirstSource = false;
} }
else { else {
absl::Span<float> temp(impl.temp_.data(), numFrames);
source.gen->generate(source.key, impl.currentVoiceId_, temp);
if (targetFlags & kModIsMultiplicative) { if (targetFlags & kModIsMultiplicative) {
for (uint32_t i = 0; i < numFrames; ++i) for (uint32_t i = 0; i < numFrames; ++i)
buffer[i] *= sourceDepth * temp[i]; buffer[i] *= sourceDepth * sourceBuffer[i];
} }
else if (targetFlags & kModIsPercentMultiplicative) { else if (targetFlags & kModIsPercentMultiplicative) {
for (uint32_t i = 0; i < numFrames; ++i) for (uint32_t i = 0; i < numFrames; ++i)
buffer[i] *= (0.01f * sourceDepth) * temp[i]; buffer[i] *= (0.01f * sourceDepth) * sourceBuffer[i];
} }
else { else {
ASSERT(targetFlags & kModIsAdditive); ASSERT(targetFlags & kModIsAdditive);
for (uint32_t i = 0; i < numFrames; ++i) for (uint32_t i = 0; i < numFrames; ++i)
buffer[i] += sourceDepth * temp[i]; buffer[i] += sourceDepth * sourceBuffer[i];
} }
} }
} }
@ -361,12 +365,12 @@ float* ModMatrix::getModulation(TargetId targetId)
// if there were no source, fill output with the neutral element // if there were no source, fill output with the neutral element
if (isFirstSource) { if (isFirstSource) {
if (targetFlags & kModIsMultiplicative) if (targetFlags & kModIsMultiplicative)
sfz::fill(buffer, 1.0f); fill(buffer, 1.0f);
else if (targetFlags & kModIsPercentMultiplicative) else if (targetFlags & kModIsPercentMultiplicative)
sfz::fill(buffer, 100.0f); fill(buffer, 100.0f);
else { else {
ASSERT(targetFlags & kModIsAdditive); ASSERT(targetFlags & kModIsAdditive);
sfz::fill(buffer, 0.0f); fill(buffer, 0.0f);
} }
} }