Noexcepts
This commit is contained in:
parent
bfa85b131d
commit
a8b2c9dfa8
8 changed files with 122 additions and 100 deletions
|
|
@ -19,7 +19,7 @@ void readFromFile(SndfileHandle& sndFile, int numFrames, StereoBuffer<T>& output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(std::string_view filename)
|
std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(std::string_view filename) noexcept
|
||||||
{
|
{
|
||||||
std::filesystem::path file { rootDirectory / filename };
|
std::filesystem::path file { rootDirectory / filename };
|
||||||
if (!std::filesystem::exists(file))
|
if (!std::filesystem::exists(file))
|
||||||
|
|
@ -60,14 +60,14 @@ std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(
|
||||||
return returnedValue;
|
return returnedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames)
|
void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames) noexcept
|
||||||
{
|
{
|
||||||
if (!loadingQueue.try_enqueue({ voice, sample, numFrames })) {
|
if (!loadingQueue.try_enqueue({ voice, sample, numFrames })) {
|
||||||
DBG("Problem enqueuing a file read for file " << sample);
|
DBG("Problem enqueuing a file read for file " << sample);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::FilePool::loadingThread()
|
void sfz::FilePool::loadingThread() noexcept
|
||||||
{
|
{
|
||||||
FileLoadingInformation fileToLoad {};
|
FileLoadingInformation fileToLoad {};
|
||||||
while (!quitThread) {
|
while (!quitThread) {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ public:
|
||||||
quitThread = true;
|
quitThread = true;
|
||||||
fileLoadingThread.join();
|
fileLoadingThread.join();
|
||||||
}
|
}
|
||||||
void setRootDirectory(const std::filesystem::path& directory) { rootDirectory = directory; }
|
void setRootDirectory(const std::filesystem::path& directory) noexcept { rootDirectory = directory; }
|
||||||
size_t getNumPreloadedSamples() { return preloadedData.size(); }
|
size_t getNumPreloadedSamples() const noexcept { return preloadedData.size(); }
|
||||||
|
|
||||||
struct FileInformation {
|
struct FileInformation {
|
||||||
uint32_t end { Default::sampleEndRange.getEnd() };
|
uint32_t end { Default::sampleEndRange.getEnd() };
|
||||||
|
|
@ -33,18 +33,8 @@ public:
|
||||||
double sampleRate { config::defaultSampleRate };
|
double sampleRate { config::defaultSampleRate };
|
||||||
std::shared_ptr<StereoBuffer<float>> preloadedData;
|
std::shared_ptr<StereoBuffer<float>> preloadedData;
|
||||||
};
|
};
|
||||||
std::optional<FileInformation> getFileInformation(std::string_view filename);
|
std::optional<FileInformation> getFileInformation(std::string_view filename) noexcept;
|
||||||
void enqueueLoading(Voice* voice, std::string_view sample, int numFrames);
|
void enqueueLoading(Voice* voice, std::string_view sample, int numFrames) noexcept;
|
||||||
static void deleteAndTrackBuffers(StereoBuffer<float>* buffer)
|
|
||||||
{
|
|
||||||
fileBuffers--;
|
|
||||||
delete buffer;
|
|
||||||
};
|
|
||||||
static int getFileBuffers()
|
|
||||||
{
|
|
||||||
return fileBuffers.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::filesystem::path rootDirectory;
|
std::filesystem::path rootDirectory;
|
||||||
struct FileLoadingInformation {
|
struct FileLoadingInformation {
|
||||||
|
|
@ -53,9 +43,8 @@ private:
|
||||||
int numFrames;
|
int numFrames;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static std::atomic<int> fileBuffers { 0 };
|
|
||||||
moodycamel::BlockingReaderWriterQueue<FileLoadingInformation> loadingQueue;
|
moodycamel::BlockingReaderWriterQueue<FileLoadingInformation> loadingQueue;
|
||||||
void loadingThread();
|
void loadingThread() noexcept;
|
||||||
std::thread fileLoadingThread;
|
std::thread fileLoadingThread;
|
||||||
bool quitThread { false };
|
bool quitThread { false };
|
||||||
absl::flat_hash_map<std::string_view, std::shared_ptr<StereoBuffer<float>>> preloadedData;
|
absl::flat_hash_map<std::string_view, std::shared_ptr<StereoBuffer<float>>> preloadedData;
|
||||||
|
|
|
||||||
|
|
@ -403,12 +403,12 @@ bool sfz::Region::parseOpcode(const Opcode& opcode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::isSwitchedOn() const noexcept
|
bool sfz::Region::isSwitchedOn() const noexcept
|
||||||
{
|
{
|
||||||
return keySwitched && previousKeySwitched && sequenceSwitched && pitchSwitched && bpmSwitched && aftertouchSwitched && allCCSwitched;
|
return keySwitched && previousKeySwitched && sequenceSwitched && pitchSwitched && bpmSwitched && aftertouchSwitched && allCCSwitched;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity, float randValue)
|
bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity, float randValue) noexcept
|
||||||
{
|
{
|
||||||
const bool chanOk = channelRange.containsWithEnd(channel);
|
const bool chanOk = channelRange.containsWithEnd(channel);
|
||||||
if (!chanOk)
|
if (!chanOk)
|
||||||
|
|
@ -468,7 +468,7 @@ bool sfz::Region::registerNoteOn(int channel, int noteNumber, uint8_t velocity,
|
||||||
return keyOk && velOk && chanOk && randOk && (attackTrigger || firstLegatoNote || notFirstLegatoNote);
|
return keyOk && velOk && chanOk && randOk && (attackTrigger || firstLegatoNote || notFirstLegatoNote);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::registerNoteOff(int channel, int noteNumber, uint8_t velocity [[maybe_unused]], float randValue)
|
bool sfz::Region::registerNoteOff(int channel, int noteNumber, uint8_t velocity [[maybe_unused]], float randValue) noexcept
|
||||||
{
|
{
|
||||||
const bool chanOk = channelRange.containsWithEnd(channel);
|
const bool chanOk = channelRange.containsWithEnd(channel);
|
||||||
if (!chanOk)
|
if (!chanOk)
|
||||||
|
|
@ -496,7 +496,7 @@ bool sfz::Region::registerNoteOff(int channel, int noteNumber, uint8_t velocity
|
||||||
return keyOk && chanOk && randOk && releaseTrigger;
|
return keyOk && chanOk && randOk && releaseTrigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::registerCC(int channel, int ccNumber, uint8_t ccValue)
|
bool sfz::Region::registerCC(int channel, int ccNumber, uint8_t ccValue) noexcept
|
||||||
{
|
{
|
||||||
if (!channelRange.containsWithEnd(channel))
|
if (!channelRange.containsWithEnd(channel))
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -517,7 +517,7 @@ bool sfz::Region::registerCC(int channel, int ccNumber, uint8_t ccValue)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Region::registerPitchWheel(int channel, int pitch)
|
void sfz::Region::registerPitchWheel(int channel, int pitch) noexcept
|
||||||
{
|
{
|
||||||
if (!channelRange.containsWithEnd(channel))
|
if (!channelRange.containsWithEnd(channel))
|
||||||
return;
|
return;
|
||||||
|
|
@ -528,7 +528,7 @@ void sfz::Region::registerPitchWheel(int channel, int pitch)
|
||||||
pitchSwitched = false;
|
pitchSwitched = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Region::registerAftertouch(int channel, uint8_t aftertouch)
|
void sfz::Region::registerAftertouch(int channel, uint8_t aftertouch) noexcept
|
||||||
{
|
{
|
||||||
if (!channelRange.containsWithEnd(channel))
|
if (!channelRange.containsWithEnd(channel))
|
||||||
return;
|
return;
|
||||||
|
|
@ -539,7 +539,7 @@ void sfz::Region::registerAftertouch(int channel, uint8_t aftertouch)
|
||||||
aftertouchSwitched = false;
|
aftertouchSwitched = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Region::registerTempo(float secondsPerQuarter)
|
void sfz::Region::registerTempo(float secondsPerQuarter) noexcept
|
||||||
{
|
{
|
||||||
const float bpm = 60.0f / secondsPerQuarter;
|
const float bpm = 60.0f / secondsPerQuarter;
|
||||||
if (bpmRange.containsWithEnd(bpm))
|
if (bpmRange.containsWithEnd(bpm))
|
||||||
|
|
@ -557,16 +557,19 @@ float sfz::Region::getBasePitchVariation(int noteNumber, uint8_t velocity) noexc
|
||||||
pitchVariationInCents += pitchDistribution(Random::randomGenerator); // random pitch changes
|
pitchVariationInCents += pitchDistribution(Random::randomGenerator); // random pitch changes
|
||||||
return centsFactor(pitchVariationInCents);
|
return centsFactor(pitchVariationInCents);
|
||||||
}
|
}
|
||||||
|
|
||||||
float sfz::Region::getBaseGain() noexcept
|
float sfz::Region::getBaseGain() noexcept
|
||||||
{
|
{
|
||||||
float baseGaindB { volume };
|
float baseGaindB { volume };
|
||||||
baseGaindB += gainDistribution(Random::randomGenerator);
|
baseGaindB += gainDistribution(Random::randomGenerator);
|
||||||
return db2mag(baseGaindB);
|
return db2mag(baseGaindB);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sfz::Region::getOffset() noexcept
|
uint32_t sfz::Region::getOffset() noexcept
|
||||||
{
|
{
|
||||||
return offset + offsetDistribution(Random::randomGenerator);
|
return offset + offsetDistribution(Random::randomGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t sfz::Region::getDelay() noexcept
|
uint32_t sfz::Region::getDelay() noexcept
|
||||||
{
|
{
|
||||||
return delay + delayDistribution(Random::randomGenerator);
|
return delay + delayDistribution(Random::randomGenerator);
|
||||||
|
|
@ -576,6 +579,7 @@ uint32_t sfz::Region::trueSampleEnd() const noexcept
|
||||||
{
|
{
|
||||||
return min(sampleEnd, loopRange.getEnd());
|
return min(sampleEnd, loopRange.getEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Region::canUsePreloadedData() const noexcept
|
bool sfz::Region::canUsePreloadedData() const noexcept
|
||||||
{
|
{
|
||||||
if (preloadedData == nullptr)
|
if (preloadedData == nullptr)
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ struct Region {
|
||||||
bool isGenerator() const noexcept { return sample.size() > 0 ? sample[0] == '*' : false; }
|
bool isGenerator() const noexcept { return sample.size() > 0 ? sample[0] == '*' : false; }
|
||||||
bool shouldLoop() const noexcept { return (loopMode == SfzLoopMode::loop_continuous || loopMode == SfzLoopMode::loop_sustain); }
|
bool shouldLoop() const noexcept { return (loopMode == SfzLoopMode::loop_continuous || loopMode == SfzLoopMode::loop_sustain); }
|
||||||
bool isSwitchedOn() const noexcept;
|
bool isSwitchedOn() const noexcept;
|
||||||
bool registerNoteOn(int channel, int noteNumber, uint8_t velocity, float randValue);
|
bool registerNoteOn(int channel, int noteNumber, uint8_t velocity, float randValue) noexcept;
|
||||||
bool registerNoteOff(int channel, int noteNumber, uint8_t velocity, float randValue);
|
bool registerNoteOff(int channel, int noteNumber, uint8_t velocity, float randValue) noexcept;
|
||||||
bool registerCC(int channel, int ccNumber, uint8_t ccValue);
|
bool registerCC(int channel, int ccNumber, uint8_t ccValue) noexcept;
|
||||||
void registerPitchWheel(int channel, int pitch);
|
void registerPitchWheel(int channel, int pitch) noexcept;
|
||||||
void registerAftertouch(int channel, uint8_t aftertouch);
|
void registerAftertouch(int channel, uint8_t aftertouch) noexcept;
|
||||||
void registerTempo(float secondsPerQuarter);
|
void registerTempo(float secondsPerQuarter) noexcept;
|
||||||
bool isStereo() const noexcept;
|
bool isStereo() const noexcept;
|
||||||
float getBasePitchVariation(int noteNumber, uint8_t velocity) noexcept;
|
float getBasePitchVariation(int noteNumber, uint8_t velocity) noexcept;
|
||||||
float getBaseGain() noexcept;
|
float getBaseGain() noexcept;
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ bool sfz::Synth::loadSfzFile(const std::filesystem::path& filename)
|
||||||
return parserReturned;
|
return parserReturned;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfz::Voice* sfz::Synth::findFreeVoice()
|
sfz::Voice* sfz::Synth::findFreeVoice() noexcept
|
||||||
{
|
{
|
||||||
auto freeVoice = absl::c_find_if(voices, [](const auto& voice) { return voice->isFree(); });
|
auto freeVoice = absl::c_find_if(voices, [](const auto& voice) { return voice->isFree(); });
|
||||||
if (freeVoice == voices.end()) {
|
if (freeVoice == voices.end()) {
|
||||||
|
|
@ -186,7 +186,7 @@ sfz::Voice* sfz::Synth::findFreeVoice()
|
||||||
return freeVoice->get();
|
return freeVoice->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::getNumActiveVoices() const
|
void sfz::Synth::getNumActiveVoices() const noexcept
|
||||||
{
|
{
|
||||||
auto activeVoices { 0 };
|
auto activeVoices { 0 };
|
||||||
for (const auto& voice : voices) {
|
for (const auto& voice : voices) {
|
||||||
|
|
@ -195,14 +195,14 @@ void sfz::Synth::getNumActiveVoices() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::garbageCollect()
|
void sfz::Synth::garbageCollect() noexcept
|
||||||
{
|
{
|
||||||
for (auto& voice : voices) {
|
for (auto& voice : voices) {
|
||||||
voice->garbageCollect();
|
voice->garbageCollect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::setSamplesPerBlock(int samplesPerBlock)
|
void sfz::Synth::setSamplesPerBlock(int samplesPerBlock) noexcept
|
||||||
{
|
{
|
||||||
DBG("[Synth] Samples per block set to " << samplesPerBlock);
|
DBG("[Synth] Samples per block set to " << samplesPerBlock);
|
||||||
this->samplesPerBlock = samplesPerBlock;
|
this->samplesPerBlock = samplesPerBlock;
|
||||||
|
|
@ -211,7 +211,7 @@ void sfz::Synth::setSamplesPerBlock(int samplesPerBlock)
|
||||||
voice->setSamplesPerBlock(samplesPerBlock);
|
voice->setSamplesPerBlock(samplesPerBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::setSampleRate(float sampleRate)
|
void sfz::Synth::setSampleRate(float sampleRate) noexcept
|
||||||
{
|
{
|
||||||
DBG("[Synth] Sample rate set to " << sampleRate);
|
DBG("[Synth] Sample rate set to " << sampleRate);
|
||||||
this->sampleRate = sampleRate;
|
this->sampleRate = sampleRate;
|
||||||
|
|
@ -219,7 +219,7 @@ void sfz::Synth::setSampleRate(float sampleRate)
|
||||||
voice->setSampleRate(sampleRate);
|
voice->setSampleRate(sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::renderBlock(StereoSpan<float> buffer)
|
void sfz::Synth::renderBlock(StereoSpan<float> buffer) noexcept
|
||||||
{
|
{
|
||||||
ScopedFTZ ftz;
|
ScopedFTZ ftz;
|
||||||
buffer.fill(0.0f);
|
buffer.fill(0.0f);
|
||||||
|
|
@ -230,7 +230,7 @@ void sfz::Synth::renderBlock(StereoSpan<float> buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::noteOn(int delay, int channel, int noteNumber, uint8_t velocity)
|
void sfz::Synth::noteOn(int delay, int channel, int noteNumber, uint8_t velocity) noexcept
|
||||||
{
|
{
|
||||||
auto randValue = randNoteDistribution(Random::randomGenerator);
|
auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||||
|
|
||||||
|
|
@ -251,7 +251,7 @@ void sfz::Synth::noteOn(int delay, int channel, int noteNumber, uint8_t velocity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::noteOff(int delay, int channel, int noteNumber, uint8_t velocity)
|
void sfz::Synth::noteOff(int delay, int channel, int noteNumber, uint8_t velocity) noexcept
|
||||||
{
|
{
|
||||||
auto randValue = randNoteDistribution(Random::randomGenerator);
|
auto randValue = randNoteDistribution(Random::randomGenerator);
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
|
|
@ -269,7 +269,7 @@ void sfz::Synth::noteOff(int delay, int channel, int noteNumber, uint8_t velocit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::cc(int delay, int channel, int ccNumber, uint8_t ccValue)
|
void sfz::Synth::cc(int delay, int channel, int ccNumber, uint8_t ccValue) noexcept
|
||||||
{
|
{
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
voice->registerCC(delay, channel, ccNumber, ccValue);
|
voice->registerCC(delay, channel, ccNumber, ccValue);
|
||||||
|
|
@ -286,4 +286,33 @@ void sfz::Synth::cc(int delay, int channel, int ccNumber, uint8_t ccValue)
|
||||||
filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd());
|
filePool.enqueueLoading(voice, region->sample, region->trueSampleEnd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int sfz::Synth::getNumRegions() const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<int>(regions.size());
|
||||||
|
}
|
||||||
|
int sfz::Synth::getNumGroups() const noexcept
|
||||||
|
{
|
||||||
|
return numGroups;
|
||||||
|
}
|
||||||
|
int sfz::Synth::getNumMasters() const noexcept
|
||||||
|
{
|
||||||
|
return numMasters;
|
||||||
|
}
|
||||||
|
int sfz::Synth::getNumCurves() const noexcept
|
||||||
|
{
|
||||||
|
return numCurves;
|
||||||
|
}
|
||||||
|
const sfz::Region* sfz::Synth::getRegionView(int idx) const noexcept
|
||||||
|
{
|
||||||
|
return (size_t)idx < regions.size() ? regions[idx].get() : nullptr;
|
||||||
|
}
|
||||||
|
std::set<std::string_view> sfz::Synth::getUnknownOpcodes() const noexcept
|
||||||
|
{
|
||||||
|
return unknownOpcodes;
|
||||||
|
}
|
||||||
|
size_t sfz::Synth::getNumPreloadedSamples() const noexcept
|
||||||
|
{
|
||||||
|
return filePool.getNumPreloadedSamples();
|
||||||
}
|
}
|
||||||
|
|
@ -22,27 +22,27 @@ public:
|
||||||
Synth();
|
Synth();
|
||||||
|
|
||||||
bool loadSfzFile(const std::filesystem::path& file) final;
|
bool loadSfzFile(const std::filesystem::path& file) final;
|
||||||
int getNumRegions() const noexcept { return static_cast<int>(regions.size()); }
|
int getNumRegions() const noexcept;
|
||||||
int getNumGroups() const noexcept { return numGroups; }
|
int getNumGroups() const noexcept;
|
||||||
int getNumMasters() const noexcept { return numMasters; }
|
int getNumMasters() const noexcept;
|
||||||
int getNumCurves() const noexcept { return numCurves; }
|
int getNumCurves() const noexcept;
|
||||||
const Region* getRegionView(int idx) const noexcept { return (size_t)idx < regions.size() ? regions[idx].get() : nullptr; }
|
const Region* getRegionView(int idx) const noexcept;
|
||||||
auto getUnknownOpcodes() { return unknownOpcodes; }
|
std::set<std::string_view> getUnknownOpcodes() const noexcept;
|
||||||
size_t getNumPreloadedSamples() { return filePool.getNumPreloadedSamples(); }
|
size_t getNumPreloadedSamples() const noexcept;
|
||||||
|
|
||||||
void setSamplesPerBlock(int samplesPerBlock);
|
void setSamplesPerBlock(int samplesPerBlock) noexcept;
|
||||||
void setSampleRate(float sampleRate);
|
void setSampleRate(float sampleRate) noexcept;
|
||||||
void renderBlock(StereoSpan<float> buffer);
|
void renderBlock(StereoSpan<float> buffer) noexcept;
|
||||||
|
|
||||||
void noteOn(int delay, int channel, int noteNumber, uint8_t velocity);
|
void noteOn(int delay, int channel, int noteNumber, uint8_t velocity) noexcept;
|
||||||
void noteOff(int delay, int channel, int noteNumber, uint8_t velocity);
|
void noteOff(int delay, int channel, int noteNumber, uint8_t velocity) noexcept;
|
||||||
void cc(int delay, int channel, int ccNumber, uint8_t ccValue);
|
void cc(int delay, int channel, int ccNumber, uint8_t ccValue) noexcept;
|
||||||
void pitchWheel(int delay, int channel, int pitch);
|
void pitchWheel(int delay, int channel, int pitch) noexcept;
|
||||||
void aftertouch(int delay, int channel, uint8_t aftertouch);
|
void aftertouch(int delay, int channel, uint8_t aftertouch) noexcept;
|
||||||
void tempo(int delay, float secondsPerQuarter);
|
void tempo(int delay, float secondsPerQuarter) noexcept;
|
||||||
|
|
||||||
void getNumActiveVoices() const;
|
void getNumActiveVoices() const noexcept;
|
||||||
void garbageCollect();
|
void garbageCollect() noexcept;
|
||||||
protected:
|
protected:
|
||||||
void callback(std::string_view header, const std::vector<Opcode>& members) final;
|
void callback(std::string_view header, const std::vector<Opcode>& members) final;
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ private:
|
||||||
|
|
||||||
FilePool filePool;
|
FilePool filePool;
|
||||||
CCValueArray ccState;
|
CCValueArray ccState;
|
||||||
Voice* findFreeVoice();
|
Voice* findFreeVoice() noexcept;
|
||||||
std::vector<CCNamePair> ccNames;
|
std::vector<CCNamePair> ccNames;
|
||||||
std::optional<uint8_t> defaultSwitch;
|
std::optional<uint8_t> defaultSwitch;
|
||||||
std::set<std::string_view> unknownOpcodes;
|
std::set<std::string_view> unknownOpcodes;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ sfz::Voice::Voice(const CCValueArray& ccState)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::startVoice(Region* region, int delay, int channel, int number, uint8_t value, sfz::Voice::TriggerType triggerType)
|
void sfz::Voice::startVoice(Region* region, int delay, int channel, int number, uint8_t value, sfz::Voice::TriggerType triggerType) noexcept
|
||||||
{
|
{
|
||||||
this->triggerType = triggerType;
|
this->triggerType = triggerType;
|
||||||
triggerNumber = number;
|
triggerNumber = number;
|
||||||
|
|
@ -32,7 +32,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int channel, int number,
|
||||||
prepareEGEnvelope(delay, value);
|
prepareEGEnvelope(delay, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::prepareEGEnvelope(int delay, uint8_t velocity)
|
void sfz::Voice::prepareEGEnvelope(int delay, uint8_t velocity) noexcept
|
||||||
{
|
{
|
||||||
auto secondsToSamples = [this](auto timeInSeconds) {
|
auto secondsToSamples = [this](auto timeInSeconds) {
|
||||||
return static_cast<int>(timeInSeconds * sampleRate);
|
return static_cast<int>(timeInSeconds * sampleRate);
|
||||||
|
|
@ -48,18 +48,18 @@ void sfz::Voice::prepareEGEnvelope(int delay, uint8_t velocity)
|
||||||
normalizePercents(region->amplitudeEG.getStart(ccState, velocity)));
|
normalizePercents(region->amplitudeEG.getStart(ccState, velocity)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::setFileData(std::unique_ptr<StereoBuffer<float>> file)
|
void sfz::Voice::setFileData(std::unique_ptr<StereoBuffer<float>> file) noexcept
|
||||||
{
|
{
|
||||||
fileData = std::move(file);
|
fileData = std::move(file);
|
||||||
dataReady.store(true);
|
dataReady.store(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sfz::Voice::isFree() const
|
bool sfz::Voice::isFree() const noexcept
|
||||||
{
|
{
|
||||||
return (region == nullptr);
|
return (region == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity [[maybe_unused]])
|
void sfz::Voice::registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity [[maybe_unused]]) noexcept
|
||||||
{
|
{
|
||||||
if (region == nullptr)
|
if (region == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
@ -78,33 +78,33 @@ void sfz::Voice::registerNoteOff(int delay, int channel, int noteNumber, uint8_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerCC(int delay, int channel [[maybe_unused]], int ccNumber, uint8_t ccValue)
|
void sfz::Voice::registerCC(int delay, int channel [[maybe_unused]], int ccNumber, uint8_t ccValue) noexcept
|
||||||
{
|
{
|
||||||
if (ccNumber == 64 && noteIsOff && ccValue < 63)
|
if (ccNumber == 64 && noteIsOff && ccValue < 63)
|
||||||
egEnvelope.startRelease(delay);
|
egEnvelope.startRelease(delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerPitchWheel(int delay [[maybe_unused]], int channel [[maybe_unused]], int pitch [[maybe_unused]])
|
void sfz::Voice::registerPitchWheel(int delay [[maybe_unused]], int channel [[maybe_unused]], int pitch [[maybe_unused]]) noexcept
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerAftertouch(int delay [[maybe_unused]], int channel [[maybe_unused]], uint8_t aftertouch [[maybe_unused]])
|
void sfz::Voice::registerAftertouch(int delay [[maybe_unused]], int channel [[maybe_unused]], uint8_t aftertouch [[maybe_unused]]) noexcept
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::registerTempo(int delay [[maybe_unused]], float secondsPerQuarter [[maybe_unused]])
|
void sfz::Voice::registerTempo(int delay [[maybe_unused]], float secondsPerQuarter [[maybe_unused]]) noexcept
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::setSampleRate(float sampleRate)
|
void sfz::Voice::setSampleRate(float sampleRate) noexcept
|
||||||
{
|
{
|
||||||
this->sampleRate = sampleRate;
|
this->sampleRate = sampleRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::setSamplesPerBlock(int samplesPerBlock)
|
void sfz::Voice::setSamplesPerBlock(int samplesPerBlock) noexcept
|
||||||
{
|
{
|
||||||
this->samplesPerBlock = samplesPerBlock;
|
this->samplesPerBlock = samplesPerBlock;
|
||||||
tempBuffer1.resize(samplesPerBlock);
|
tempBuffer1.resize(samplesPerBlock);
|
||||||
|
|
@ -115,7 +115,7 @@ void sfz::Voice::setSamplesPerBlock(int samplesPerBlock)
|
||||||
indexSpan = absl::MakeSpan(indexBuffer);
|
indexSpan = absl::MakeSpan(indexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::renderBlock(StereoSpan<float> buffer)
|
void sfz::Voice::renderBlock(StereoSpan<float> buffer) noexcept
|
||||||
{
|
{
|
||||||
const auto numSamples = buffer.size();
|
const auto numSamples = buffer.size();
|
||||||
ASSERT(static_cast<int>(numSamples) <= samplesPerBlock);
|
ASSERT(static_cast<int>(numSamples) <= samplesPerBlock);
|
||||||
|
|
@ -139,7 +139,7 @@ void sfz::Voice::renderBlock(StereoSpan<float> buffer)
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::fillWithData(StereoSpan<float> buffer)
|
void sfz::Voice::fillWithData(StereoSpan<float> buffer) noexcept
|
||||||
{
|
{
|
||||||
auto source { [&]() {
|
auto source { [&]() {
|
||||||
if (region->canUsePreloadedData() || !dataReady)
|
if (region->canUsePreloadedData() || !dataReady)
|
||||||
|
|
@ -195,7 +195,7 @@ void sfz::Voice::fillWithData(StereoSpan<float> buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::fillWithGenerator(StereoSpan<float> buffer)
|
void sfz::Voice::fillWithGenerator(StereoSpan<float> buffer) noexcept
|
||||||
{
|
{
|
||||||
if (region->sample != "*sine")
|
if (region->sample != "*sine")
|
||||||
return;
|
return;
|
||||||
|
|
@ -219,27 +219,27 @@ bool sfz::Voice::checkOffGroup(int delay [[maybe_unused]], uint32_t group) noexc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfz::Voice::getTriggerNumber() const
|
int sfz::Voice::getTriggerNumber() const noexcept
|
||||||
{
|
{
|
||||||
return triggerNumber;
|
return triggerNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sfz::Voice::getTriggerChannel() const
|
int sfz::Voice::getTriggerChannel() const noexcept
|
||||||
{
|
{
|
||||||
return triggerNumber;
|
return triggerNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sfz::Voice::getTriggerValue() const
|
uint8_t sfz::Voice::getTriggerValue() const noexcept
|
||||||
{
|
{
|
||||||
return triggerNumber;
|
return triggerNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
sfz::Voice::TriggerType sfz::Voice::getTriggerType() const
|
sfz::Voice::TriggerType sfz::Voice::getTriggerType() const noexcept
|
||||||
{
|
{
|
||||||
return triggerType;
|
return triggerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::reset()
|
void sfz::Voice::reset() noexcept
|
||||||
{
|
{
|
||||||
dataReady.store(false);
|
dataReady.store(false);
|
||||||
state = State::idle;
|
state = State::idle;
|
||||||
|
|
@ -252,7 +252,7 @@ void sfz::Voice::reset()
|
||||||
noteIsOff = false;
|
noteIsOff = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Voice::garbageCollect()
|
void sfz::Voice::garbageCollect() noexcept
|
||||||
{
|
{
|
||||||
if (state == State::idle && region == nullptr)
|
if (state == State::idle && region == nullptr)
|
||||||
fileData.reset();
|
fileData.reset();
|
||||||
|
|
|
||||||
|
|
@ -17,33 +17,33 @@ public:
|
||||||
NoteOff,
|
NoteOff,
|
||||||
CC
|
CC
|
||||||
};
|
};
|
||||||
void setSampleRate(float sampleRate);
|
void setSampleRate(float sampleRate) noexcept;
|
||||||
void setSamplesPerBlock(int samplesPerBlock);
|
void setSamplesPerBlock(int samplesPerBlock) noexcept;
|
||||||
|
|
||||||
void startVoice(Region* region, int delay, int channel, int number, uint8_t value, TriggerType triggerType);
|
void startVoice(Region* region, int delay, int channel, int number, uint8_t value, TriggerType triggerType) noexcept;
|
||||||
|
|
||||||
void setFileData(std::unique_ptr<StereoBuffer<float>> file);
|
void setFileData(std::unique_ptr<StereoBuffer<float>> file) noexcept;
|
||||||
void registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity);
|
void registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity) noexcept;
|
||||||
void registerCC(int delay, int channel, int ccNumber, uint8_t ccValue);
|
void registerCC(int delay, int channel, int ccNumber, uint8_t ccValue) noexcept;
|
||||||
void registerPitchWheel(int delay, int channel, int pitch);
|
void registerPitchWheel(int delay, int channel, int pitch) noexcept;
|
||||||
void registerAftertouch(int delay, int channel, uint8_t aftertouch);
|
void registerAftertouch(int delay, int channel, uint8_t aftertouch) noexcept;
|
||||||
void registerTempo(int delay, float secondsPerQuarter);
|
void registerTempo(int delay, float secondsPerQuarter) noexcept;
|
||||||
bool checkOffGroup(int delay [[maybe_unused]], uint32_t group) noexcept;
|
bool checkOffGroup(int delay [[maybe_unused]], uint32_t group) noexcept;
|
||||||
|
|
||||||
void renderBlock(StereoSpan<float> buffer);
|
void renderBlock(StereoSpan<float> buffer) noexcept;
|
||||||
|
|
||||||
bool isFree() const;
|
bool isFree() const noexcept;
|
||||||
int getTriggerNumber() const;
|
int getTriggerNumber() const noexcept;
|
||||||
int getTriggerChannel() const;
|
int getTriggerChannel() const noexcept;
|
||||||
uint8_t getTriggerValue() const;
|
uint8_t getTriggerValue() const noexcept;
|
||||||
TriggerType getTriggerType() const;
|
TriggerType getTriggerType() const noexcept;
|
||||||
|
|
||||||
void reset();
|
void reset() noexcept;
|
||||||
void garbageCollect();
|
void garbageCollect() noexcept;
|
||||||
private:
|
private:
|
||||||
void fillWithData(StereoSpan<float> buffer);
|
void fillWithData(StereoSpan<float> buffer) noexcept;
|
||||||
void fillWithGenerator(StereoSpan<float> buffer);
|
void fillWithGenerator(StereoSpan<float> buffer) noexcept;
|
||||||
void prepareEGEnvelope(int delay, uint8_t velocity);
|
void prepareEGEnvelope(int delay, uint8_t velocity) noexcept;
|
||||||
|
|
||||||
Region* region { nullptr };
|
Region* region { nullptr };
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue