Implement the identifier in a better and more safe way
This commit is contained in:
parent
c239629be1
commit
e07912f7ce
6 changed files with 49 additions and 15 deletions
31
src/sfizz/NumericId.h
Normal file
31
src/sfizz/NumericId.h
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
// SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
// This code is part of the sfizz library and is licensed under a BSD 2-clause
|
||||||
|
// license. You should have receive a LICENSE.md file along with the code.
|
||||||
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Numeric identifier
|
||||||
|
*
|
||||||
|
* It is a generic numeric identifier. The template wrapper serves to enforce a
|
||||||
|
* stronger compile-time check, such that one kind of identifier can't be
|
||||||
|
* mistaken for another kind, or for an unrelated integer such as an index.
|
||||||
|
*/
|
||||||
|
template <class T>
|
||||||
|
struct NumericId {
|
||||||
|
constexpr NumericId() = default;
|
||||||
|
|
||||||
|
explicit constexpr NumericId(int number)
|
||||||
|
: number(number)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr bool valid() const noexcept
|
||||||
|
{
|
||||||
|
return number != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int number = -1;
|
||||||
|
};
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
#include "AudioBuffer.h"
|
#include "AudioBuffer.h"
|
||||||
#include "MidiState.h"
|
#include "MidiState.h"
|
||||||
#include "FileId.h"
|
#include "FileId.h"
|
||||||
|
#include "NumericId.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -36,7 +37,7 @@ namespace sfz {
|
||||||
*/
|
*/
|
||||||
struct Region {
|
struct Region {
|
||||||
Region(int regionNumber, const MidiState& midiState, absl::string_view defaultPath = "")
|
Region(int regionNumber, const MidiState& midiState, absl::string_view defaultPath = "")
|
||||||
: regionNumber(regionNumber), midiState(midiState), defaultPath(std::move(defaultPath))
|
: id{regionNumber}, midiState(midiState), defaultPath(std::move(defaultPath))
|
||||||
{
|
{
|
||||||
ccSwitched.set();
|
ccSwitched.set();
|
||||||
|
|
||||||
|
|
@ -49,9 +50,9 @@ struct Region {
|
||||||
/**
|
/**
|
||||||
* @brief Get the number which identifies this region
|
* @brief Get the number which identifies this region
|
||||||
*/
|
*/
|
||||||
int getIdNumber() const noexcept
|
NumericId<Region> getId() const noexcept
|
||||||
{
|
{
|
||||||
return regionNumber;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -246,7 +247,7 @@ struct Region {
|
||||||
*/
|
*/
|
||||||
float getGainToEffectBus(unsigned number) const noexcept;
|
float getGainToEffectBus(unsigned number) const noexcept;
|
||||||
|
|
||||||
const int regionNumber { -1 };
|
const NumericId<Region> id;
|
||||||
|
|
||||||
// Sound source: sample playback
|
// Sound source: sample playback
|
||||||
FileId sampleId {}; // Sample
|
FileId sampleId {}; // Sample
|
||||||
|
|
|
||||||
|
|
@ -44,11 +44,11 @@ sfz::Synth::~Synth()
|
||||||
resources.filePool.emptyFileLoadingQueues();
|
resources.filePool.emptyFileLoadingQueues();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::onVoiceStateChanged(int idNumber, Voice::State state)
|
void sfz::Synth::onVoiceStateChanged(NumericId<Voice> id, Voice::State state)
|
||||||
{
|
{
|
||||||
(void)idNumber;
|
(void)id;
|
||||||
(void)state;
|
(void)state;
|
||||||
DBG("Voice " << idNumber << ": state " << static_cast<int>(state));
|
DBG("Voice " << id.number << ": state " << static_cast<int>(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sfz::Synth::onParseFullBlock(const std::string& header, const std::vector<Opcode>& members)
|
void sfz::Synth::onParseFullBlock(const std::string& header, const std::vector<Opcode>& members)
|
||||||
|
|
|
||||||
|
|
@ -497,7 +497,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* @brief The voice callback which is called during a change of state.
|
* @brief The voice callback which is called during a change of state.
|
||||||
*/
|
*/
|
||||||
void onVoiceStateChanged(int idNumber, Voice::State state) override;
|
void onVoiceStateChanged(NumericId<Voice> idNumber, Voice::State state) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
#include "absl/algorithm/container.h"
|
#include "absl/algorithm/container.h"
|
||||||
|
|
||||||
sfz::Voice::Voice(int voiceNumber, sfz::Resources& resources)
|
sfz::Voice::Voice(int voiceNumber, sfz::Resources& resources)
|
||||||
: voiceNumber(voiceNumber), stateListener(nullptr), resources(resources)
|
: id{voiceNumber}, stateListener(nullptr), resources(resources)
|
||||||
{
|
{
|
||||||
filters.reserve(config::filtersPerVoice);
|
filters.reserve(config::filtersPerVoice);
|
||||||
equalizers.reserve(config::eqsPerVoice);
|
equalizers.reserve(config::eqsPerVoice);
|
||||||
|
|
@ -773,6 +773,6 @@ void sfz::Voice::switchState(State s)
|
||||||
if (s != state) {
|
if (s != state) {
|
||||||
state = s;
|
state = s;
|
||||||
if (stateListener)
|
if (stateListener)
|
||||||
stateListener->onVoiceStateChanged(voiceNumber, s);
|
stateListener->onVoiceStateChanged(id, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include "AudioSpan.h"
|
#include "AudioSpan.h"
|
||||||
#include "LeakDetector.h"
|
#include "LeakDetector.h"
|
||||||
#include "OnePoleFilter.h"
|
#include "OnePoleFilter.h"
|
||||||
|
#include "NumericId.h"
|
||||||
#include "absl/types/span.h"
|
#include "absl/types/span.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
@ -41,12 +42,13 @@ public:
|
||||||
NoteOff,
|
NoteOff,
|
||||||
CC
|
CC
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number which identifies this voice
|
* @brief Get the unique identifier of this voice in a synth
|
||||||
*/
|
*/
|
||||||
int getIdNumber() const noexcept
|
NumericId<Voice> getId() const noexcept
|
||||||
{
|
{
|
||||||
return voiceNumber;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class State {
|
enum class State {
|
||||||
|
|
@ -56,7 +58,7 @@ public:
|
||||||
|
|
||||||
class StateListener {
|
class StateListener {
|
||||||
public:
|
public:
|
||||||
virtual void onVoiceStateChanged(int /*idNumber*/, State /*state*/) {}
|
virtual void onVoiceStateChanged(NumericId<Voice> /*id*/, State /*state*/) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -299,7 +301,7 @@ private:
|
||||||
*/
|
*/
|
||||||
void switchState(State s);
|
void switchState(State s);
|
||||||
|
|
||||||
const int voiceNumber { -1 };
|
const NumericId<Voice> id;
|
||||||
StateListener* stateListener = nullptr;
|
StateListener* stateListener = nullptr;
|
||||||
|
|
||||||
Region* region { nullptr };
|
Region* region { nullptr };
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue