Initial grafting of the filters in the voice process (untested)

This commit is contained in:
Paul Fd 2020-02-09 14:45:11 +01:00
parent 3aaf0005ab
commit d455ee5232
5 changed files with 65 additions and 2 deletions

View file

@ -53,7 +53,9 @@ namespace config {
constexpr uint8_t numCCs { 143 };
constexpr int chunkSize { 1024 };
constexpr float defaultAmpEGRelease { 0.02f };
constexpr int defaultNumFilters { maxVoices * 2 };
constexpr int filtersInPool { maxVoices * 2 };
constexpr int filtersPerVoice { 2 };
constexpr int eqsPerVoice { 3 };
/**
Minimum interval in frames between recomputations of coefficients of the
modulated filter. The lower, the more CPU resources are consumed.

View file

@ -77,7 +77,7 @@ public:
* @param state the associated midi state
* @param numFilters the number of inactive filters to hold in the pool
*/
FilterPool(const MidiState& state, int numFilters = config::defaultNumFilters);
FilterPool(const MidiState& state, int numFilters = config::filtersInPool);
/**
* @brief Get a filter object to use in Voices
*

View file

@ -234,6 +234,9 @@ bool sfz::Synth::loadSfzFile(const fs::path& file)
++lastRegion;
};
size_t maxFilters { 0 };
size_t maxEQs { 0 };
while (currentRegion < lastRegion.base()) {
auto region = currentRegion->get();
@ -316,6 +319,8 @@ bool sfz::Synth::loadSfzFile(const fs::path& file)
region->registerPitchWheel(0);
region->registerAftertouch(0);
region->registerTempo(2.0f);
maxFilters = max(maxFilters, region->filters.size());
maxEQs = max(maxEQs, region->equalizers.size());
++currentRegion;
}
@ -324,6 +329,11 @@ bool sfz::Synth::loadSfzFile(const fs::path& file)
regions.resize(remainingRegions);
modificationTime = checkModificationTime();
for (auto& voice: voices) {
voice->setMaxFiltersPerVoice(maxFilters);
voice->setMaxEQsPerVoice(maxEQs);
}
return parserReturned;
}

View file

@ -17,6 +17,8 @@
sfz::Voice::Voice(sfz::Resources& resources)
: resources(resources)
{
filters.reserve(config::filtersPerVoice);
equalizers.reserve(config::filtersPerVoice);
}
void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value, sfz::Voice::TriggerType triggerType) noexcept
@ -85,6 +87,18 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, uint8_t value
});
pitchBendEnvelope.reset(static_cast<float>(resources.midiState.getPitchBend()));
// Check that we can handle the number of filters; filters should be cleared here
ASSERT((filters.capacity() - filters.size()) >= region->filters.size());
ASSERT((equalizers.capacity() - equalizers.size()) >= region->equalizers.size());
for(auto& filter: region->filters) {
auto newFilter = resources.filterPool.getFilter(filter, number, value);
if (newFilter)
filters.push_back(newFilter);
}
// TODO: Equalizers
sourcePosition = region->getOffset();
triggerDelay = delay;
initialDelay = delay + static_cast<uint32_t>(region->getDelay() * sampleRate);
@ -258,6 +272,12 @@ void sfz::Voice::renderBlock(AudioSpan<float> buffer) noexcept
else
processMono(buffer);
const float* inputChannels[2] { buffer.getChannel(0), buffer.getChannel(1) };
float* outputChannels[2] { buffer.getChannel(0), buffer.getChannel(1) };
for (auto filter: filters) {
filter->process(inputChannels, outputChannels, buffer.getNumFrames());
}
if (!egEnvelope.isSmoothing())
reset();
@ -528,6 +548,8 @@ void sfz::Voice::reset() noexcept
sourcePosition = 0;
floatPositionOffset = 0.0f;
noteIsOff = false;
filters.clear();
equalizers.clear();
}
float sfz::Voice::getMeanSquaredAverage() const noexcept
@ -544,3 +566,17 @@ uint32_t sfz::Voice::getSourcePosition() const noexcept
{
return sourcePosition;
}
void sfz::Voice::setMaxFiltersPerVoice(size_t numFilters)
{
// There are filters in there, this call is unexpected
ASSERT(filters.size() == 0);
filters.reserve(numFilters);
}
void sfz::Voice::setMaxEQsPerVoice(size_t numFilters)
{
// There are filters in there, this call is unexpected
ASSERT(filters.size() == 0);
filters.reserve(numFilters);
}

View file

@ -196,6 +196,18 @@ public:
* @return
*/
const Region* getRegion() const noexcept { return region; }
/**
* @brief Set the max number of filters per voice
*
* @param numFilters
*/
void setMaxFiltersPerVoice(size_t numFilters);
/**
* @brief Set the max number of EQs per voice
*
* @param numFilters
*/
void setMaxEQsPerVoice(size_t numEQs);
private:
/**
* @brief Fill a span with data from a file source. This is the first step
@ -283,6 +295,9 @@ private:
Resources& resources;
std::vector<FilterHolderPtr> filters;
std::vector<FilterHolderPtr> equalizers;
ADSREnvelope<float> egEnvelope;
LinearEnvelope<float> amplitudeEnvelope; // linear events
LinearEnvelope<float> crossfadeEnvelope;