Added a dynamic number of voices

This commit is contained in:
Paul Ferrand 2019-11-20 22:35:51 +01:00
parent 4d8032b354
commit 2b9737bcfb
4 changed files with 63 additions and 5 deletions

View file

@ -35,11 +35,9 @@
#include <utility>
using namespace std::literals;
sfz::Synth::Synth()
sfz::Synth::Synth(int numVoices)
{
for (int i = 0; i < config::numVoices; ++i)
voices.push_back(std::make_unique<Voice>(midiState));
voiceViewArray.reserve(config::numVoices);
resetVoices(numVoices);
}
void sfz::Synth::callback(absl::string_view header, const std::vector<Opcode>& members)
@ -506,4 +504,29 @@ float sfz::Synth::getVolume() const noexcept
void sfz::Synth::setVolume(float volume) noexcept
{
this->volume = Default::volumeRange.clamp(volume);
}
int sfz::Synth::getNumVoices() const noexcept
{
return numVoices;
}
void sfz::Synth::setNumVoices(int numVoices) noexcept
{
ASSERT(numVoices > 0);
resetVoices(numVoices);
}
void sfz::Synth::resetVoices(int numVoices)
{
AtomicDisabler callbackDisabler{ canEnterCallback };
while (inCallback) {
std::this_thread::sleep_for(1ms);
}
voices.clear();
for (int i = 0; i < numVoices; ++i)
voices.push_back(std::make_unique<Voice>(midiState));
voiceViewArray.reserve(numVoices);
this->numVoices = numVoices;
}

View file

@ -39,7 +39,8 @@ namespace sfz {
class Synth : public Parser {
public:
Synth();
Synth() {}
Synth(int numVoices);
bool loadSfzFile(const fs::path& file) final;
int getNumRegions() const noexcept;
int getNumGroups() const noexcept;
@ -63,6 +64,8 @@ public:
void tempo(int delay, float secondsPerQuarter) noexcept;
int getNumActiveVoices() const noexcept;
int getNumVoices() const noexcept;
void setNumVoices(int numVoices) noexcept;
void garbageCollect() noexcept;
protected:
void callback(absl::string_view header, const std::vector<Opcode>& members) final;
@ -74,6 +77,7 @@ private:
int numMasters { 0 };
int numCurves { 0 };
void clear();
void resetVoices(int numVoices);
void handleGlobalOpcodes(const std::vector<Opcode>& members);
void handleControlOpcodes(const std::vector<Opcode>& members);
void buildRegion(const std::vector<Opcode>& regionOpcodes);
@ -107,6 +111,8 @@ private:
std::atomic<bool> canEnterCallback { true };
std::atomic<bool> inCallback { false };
int numVoices { config::numVoices };
LEAK_DETECTOR(Synth);
};

View file

@ -24,6 +24,7 @@
#include "Synth.h"
#include "sfizz.h"
#define UNUSED(x) (void)(x)
#ifdef __cplusplus
extern "C" {
#endif
@ -122,6 +123,7 @@ void sfizz_render_block(sfizz_synth_t* synth, float** channels, int num_channels
auto self = reinterpret_cast<sfz::Synth*>(synth);
// Only stereo output is supported for now
ASSERT(num_channels == 2);
UNUSED(num_channels);
self->renderBlock({{channels[0], channels[1]}, static_cast<size_t>(num_frames)});
}
@ -143,6 +145,18 @@ float sfizz_get_volume(sfizz_synth_t* synth)
return self->getVolume();
}
void sfizz_set_num_voices(sfizz_synth_t* synth, int num_voices)
{
auto self = reinterpret_cast<sfz::Synth*>(synth);
self->setNumVoices(num_voices);
}
int sfizz_get_num_voices(sfizz_synth_t* synth)
{
auto self = reinterpret_cast<sfz::Synth*>(synth);
return self->getNumVoices();
}
#ifdef __cplusplus
}
#endif

View file

@ -232,6 +232,21 @@ void sfizz_set_volume(sfizz_synth_t* synth, float volume);
*/
float sfizz_get_volume(sfizz_synth_t* synth);
/**
* @brief Sets the number of voices used by the synth
*
* @param synth
* @param num_voices
*/
void sfizz_set_num_voices(sfizz_synth_t* synth, int num_voices);
/**
* @brief Returns the number of voices
*
* @param synth
* @return num_voices
*/
int sfizz_get_num_voices(sfizz_synth_t* synth);
#ifdef __cplusplus
}
#endif