Voice and synth logic
This commit is contained in:
parent
31c8c1b62e
commit
215a5fdb57
3 changed files with 54 additions and 24 deletions
|
|
@ -8,16 +8,15 @@ std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(
|
|||
std::filesystem::path file { rootDirectory / filename };
|
||||
if (!std::filesystem::exists(file))
|
||||
return {};
|
||||
|
||||
SndfileHandle sndFile ( reinterpret_cast<const char*>(file.c_str()) );
|
||||
|
||||
SndfileHandle sndFile(reinterpret_cast<const char*>(file.c_str()));
|
||||
FileInformation returnedValue;
|
||||
returnedValue.end = static_cast<uint32_t>(sndFile.frames());
|
||||
returnedValue.sampleRate = static_cast<double>(sndFile.samplerate());
|
||||
SF_INSTRUMENT instrumentInfo;
|
||||
sndFile.command(SFC_GET_INSTRUMENT, &instrumentInfo, sizeof(instrumentInfo));
|
||||
|
||||
if (instrumentInfo.loop_count == 1)
|
||||
{
|
||||
if (instrumentInfo.loop_count == 1) {
|
||||
returnedValue.loopBegin = instrumentInfo.loops[0].start;
|
||||
returnedValue.loopEnd = instrumentInfo.loops[0].end;
|
||||
}
|
||||
|
|
@ -34,8 +33,7 @@ std::optional<sfz::FilePool::FileInformation> sfz::FilePool::getFileInformation(
|
|||
|
||||
void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int numFrames)
|
||||
{
|
||||
if (!loadingQueue.try_enqueue({ voice, sample, numFrames }))
|
||||
{
|
||||
if (!loadingQueue.try_enqueue({ voice, sample, numFrames })) {
|
||||
DBG("Problem enqueuing a file read for file " << sample);
|
||||
}
|
||||
}
|
||||
|
|
@ -43,31 +41,27 @@ void sfz::FilePool::enqueueLoading(Voice* voice, std::string_view sample, int nu
|
|||
void sfz::FilePool::loadingThread()
|
||||
{
|
||||
FileLoadingInformation fileToLoad {};
|
||||
while (!quitThread)
|
||||
{
|
||||
while (!quitThread) {
|
||||
if (!loadingQueue.wait_dequeue_timed(fileToLoad, 1ms))
|
||||
continue;
|
||||
|
||||
if (fileToLoad.voice == nullptr)
|
||||
{
|
||||
if (fileToLoad.voice == nullptr) {
|
||||
DBG("Background thread error: voice is null.");
|
||||
continue;
|
||||
}
|
||||
|
||||
DBG("Background loading of: " << fileToLoad.sample);
|
||||
std::filesystem::path file { rootDirectory / fileToLoad.sample };
|
||||
if (!std::filesystem::exists(file))
|
||||
{
|
||||
if (!std::filesystem::exists(file)) {
|
||||
DBG("Background thread: no file " << fileToLoad.sample << " exists.");
|
||||
continue;
|
||||
}
|
||||
|
||||
SndfileHandle sndFile ( reinterpret_cast<const char*>(file.c_str()) );
|
||||
|
||||
SndfileHandle sndFile(reinterpret_cast<const char*>(file.c_str()));
|
||||
auto fileLoaded = std::make_unique<StereoBuffer<float>>(fileToLoad.numFrames);
|
||||
auto readBuffer = std::make_unique<Buffer<float>>(fileToLoad.numFrames * 2);
|
||||
sndFile.readf(readBuffer->data(), fileToLoad.numFrames);
|
||||
fileLoaded->readInterleaved(*readBuffer);
|
||||
fileToLoad.voice->setFileData(std::move(fileLoaded));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
#include "Parser.h"
|
||||
#include "Region.h"
|
||||
#include "SfzHelpers.h"
|
||||
#include "absl/types/span.h"
|
||||
#include <optional>
|
||||
#include <random>
|
||||
#include <set>
|
||||
|
|
@ -36,6 +37,8 @@ public:
|
|||
|
||||
void renderBlock(StereoBuffer<float>& buffer)
|
||||
{
|
||||
buffer.fill(0.0f);
|
||||
|
||||
for (auto& voice : voices) {
|
||||
voice->renderBlock(tempBuffer);
|
||||
buffer.add(tempBuffer);
|
||||
|
|
@ -45,11 +48,16 @@ public:
|
|||
void noteOn(int delay, int channel, int noteNumber, uint8_t velocity)
|
||||
{
|
||||
auto randValue = getUniform();
|
||||
for (auto& voice : voices)
|
||||
voice->registerNoteOn(delay, channel, noteNumber, velocity);
|
||||
|
||||
for (auto& region : regions) {
|
||||
if (region->registerNoteOn(channel, noteNumber, velocity, randValue)) {
|
||||
|
||||
for (auto& voice: voices)
|
||||
{
|
||||
if (voice->checkOffGroup(delay, region->group))
|
||||
noteOff(delay, voice->getTriggerChannel(), voice->getTriggerNumber(), 0);
|
||||
}
|
||||
|
||||
auto voice = findFreeVoice();
|
||||
if (voice == nullptr)
|
||||
continue;
|
||||
|
|
@ -62,11 +70,8 @@ public:
|
|||
void noteOff(int delay, int channel, int noteNumber, uint8_t velocity)
|
||||
{
|
||||
auto randValue = getUniform();
|
||||
for (auto& voice : voices) {
|
||||
if (voice->registerNoteOff(delay, channel, noteNumber, velocity)) {
|
||||
// do something
|
||||
}
|
||||
}
|
||||
for (auto& voice : voices)
|
||||
voice->registerNoteOff(delay, channel, noteNumber, velocity);
|
||||
|
||||
for (auto& region : regions) {
|
||||
if (region->registerNoteOff(channel, noteNumber, velocity, randValue)) {
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ public:
|
|||
return (region == nullptr);
|
||||
}
|
||||
|
||||
void registerNoteOn(int delay, int channel, int noteNumber, uint8_t velocity);
|
||||
bool registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity);
|
||||
void registerNoteOff(int delay, int channel, int noteNumber, uint8_t velocity);
|
||||
bool registerCC(int delay, int channel, int ccNumber, uint8_t ccValue);
|
||||
void registerPitchWheel(int delay, int channel, int pitch);
|
||||
void registerAftertouch(int delay, int channel, uint8_t aftertouch);
|
||||
|
|
@ -45,6 +44,38 @@ public:
|
|||
buffer.fill(0.0f);
|
||||
}
|
||||
|
||||
bool checkOffGroup(int delay [[maybe_unused]], uint32_t group) noexcept
|
||||
{
|
||||
if (region != nullptr && triggerType == TriggerType::NoteOn && region->offBy && *region->offBy == group )
|
||||
{
|
||||
// TODO: release
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int getTriggerNumber() const
|
||||
{
|
||||
return triggerNumber;
|
||||
}
|
||||
|
||||
int getTriggerChannel() const
|
||||
{
|
||||
return triggerNumber;
|
||||
}
|
||||
|
||||
uint8_t getTriggerValue() const
|
||||
{
|
||||
return triggerNumber;
|
||||
}
|
||||
|
||||
TriggerType getTriggerType() const
|
||||
{
|
||||
return triggerType;
|
||||
}
|
||||
|
||||
|
||||
void reset()
|
||||
{
|
||||
dataReady.store(false);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue