Add a listener of voice state changes
This commit is contained in:
parent
f0f4c34ad8
commit
2c3314d0ad
4 changed files with 54 additions and 10 deletions
|
|
@ -44,6 +44,13 @@ sfz::Synth::~Synth()
|
|||
resources.filePool.emptyFileLoadingQueues();
|
||||
}
|
||||
|
||||
void sfz::Synth::onVoiceStateChanged(int idNumber, Voice::State state)
|
||||
{
|
||||
(void)idNumber;
|
||||
(void)state;
|
||||
DBG("Voice " << idNumber << ": state " << static_cast<int>(state));
|
||||
}
|
||||
|
||||
void sfz::Synth::onParseFullBlock(const std::string& header, const std::vector<Opcode>& members)
|
||||
{
|
||||
switch (hash(header)) {
|
||||
|
|
@ -1094,8 +1101,11 @@ void sfz::Synth::resetVoices(int numVoices)
|
|||
voices.clear();
|
||||
voices.reserve(numVoices);
|
||||
|
||||
for (int i = 0; i < numVoices; ++i)
|
||||
voices.push_back(absl::make_unique<Voice>(i, resources));
|
||||
for (int i = 0; i < numVoices; ++i) {
|
||||
auto voice = absl::make_unique<Voice>(i, resources);
|
||||
voice->setStateListener(this);
|
||||
voices.emplace_back(std::move(voice));
|
||||
}
|
||||
|
||||
voiceViewArray.clear();
|
||||
voiceViewArray.reserve(numVoices);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ namespace sfz {
|
|||
* The jack_client.cpp file contains examples of the most classical usage of the
|
||||
* synth and can be used as a reference.
|
||||
*/
|
||||
class Synth final : public Parser::Listener {
|
||||
class Synth final : public Voice::StateListener, public Parser::Listener {
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Synth object with no voices. If you want sound
|
||||
|
|
@ -493,6 +493,12 @@ public:
|
|||
*/
|
||||
const std::vector<CCNamePair>& getCCLabels() const noexcept { return ccLabels; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief The voice callback which is called during a change of state.
|
||||
*/
|
||||
void onVoiceStateChanged(int idNumber, Voice::State state) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief The parser callback; this is called by the parent object each time
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include "absl/algorithm/container.h"
|
||||
|
||||
sfz::Voice::Voice(int voiceNumber, sfz::Resources& resources)
|
||||
: voiceNumber(voiceNumber), resources(resources)
|
||||
: voiceNumber(voiceNumber), stateListener(nullptr), resources(resources)
|
||||
{
|
||||
filters.reserve(config::filtersPerVoice);
|
||||
equalizers.reserve(config::eqsPerVoice);
|
||||
|
|
@ -36,7 +36,7 @@ void sfz::Voice::startVoice(Region* region, int delay, int number, float value,
|
|||
triggerValue = value;
|
||||
|
||||
this->region = region;
|
||||
state = State::playing;
|
||||
switchState(State::playing);
|
||||
|
||||
ASSERT(delay >= 0);
|
||||
if (delay < 0)
|
||||
|
|
@ -647,7 +647,7 @@ bool sfz::Voice::checkOffGroup(int delay, uint32_t group) noexcept
|
|||
|
||||
void sfz::Voice::reset() noexcept
|
||||
{
|
||||
state = State::idle;
|
||||
switchState(State::idle);
|
||||
region = nullptr;
|
||||
currentPromise.reset();
|
||||
sourcePosition = 0;
|
||||
|
|
@ -766,3 +766,13 @@ void sfz::Voice::updateChannelPowers(AudioSpan<float> buffer)
|
|||
channelEnvelopeFilters[i].tickLowpass(std::abs(input[s]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sfz::Voice::switchState(State s)
|
||||
{
|
||||
if (s != state) {
|
||||
state = s;
|
||||
if (stateListener)
|
||||
stateListener->onVoiceStateChanged(voiceNumber, s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,22 @@ public:
|
|||
{
|
||||
return voiceNumber;
|
||||
}
|
||||
|
||||
enum class State {
|
||||
idle,
|
||||
playing
|
||||
};
|
||||
|
||||
class StateListener {
|
||||
public:
|
||||
virtual void onVoiceStateChanged(int /*idNumber*/, State /*state*/) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Sets the listener which is called when the voice state changes.
|
||||
*/
|
||||
void setStateListener(StateListener *l) noexcept { stateListener = l; }
|
||||
|
||||
/**
|
||||
* @brief Change the sample rate of the voice. This is used to compute all
|
||||
* pitch related transformations so it needs to be propagated from the synth
|
||||
|
|
@ -278,14 +294,16 @@ private:
|
|||
void setupOscillatorUnison();
|
||||
void updateChannelPowers(AudioSpan<float> buffer);
|
||||
|
||||
/**
|
||||
* @brief Modify the voice state and notify any listeners.
|
||||
*/
|
||||
void switchState(State s);
|
||||
|
||||
const int voiceNumber {};
|
||||
StateListener* stateListener = nullptr;
|
||||
|
||||
Region* region { nullptr };
|
||||
|
||||
enum class State {
|
||||
idle,
|
||||
playing
|
||||
};
|
||||
State state { State::idle };
|
||||
bool noteIsOff { false };
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue