Store the initial values of controllers
This commit is contained in:
parent
f0dd146361
commit
3cf7536c57
3 changed files with 71 additions and 4 deletions
|
|
@ -231,8 +231,9 @@ void sfz::Synth::clear()
|
|||
modificationTime = fs::file_time_type::min();
|
||||
|
||||
// set default controllers
|
||||
cc(0, 7, 100); // volume
|
||||
hdcc(0, 10, 0.5f); // pan
|
||||
fill(absl::MakeSpan(ccInitialValues), 0.0f);
|
||||
initCc(7, 100); // volume
|
||||
initHdcc(10, 0.5f); // pan
|
||||
|
||||
// set default controller labels
|
||||
insertPairUniquely(ccLabels, 7, "Volume");
|
||||
|
|
@ -326,14 +327,14 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
|
|||
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
||||
const auto ccValue = readOpcode(member.value, Default::midi7Range);
|
||||
if (ccValue)
|
||||
resources.midiState.ccEvent(0, member.parameters.back(), normalizeCC(*ccValue));
|
||||
initCc(member.parameters.back(), *ccValue);
|
||||
}
|
||||
break;
|
||||
case hash("set_hdcc&"):
|
||||
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
|
||||
const auto ccValue = readOpcode(member.value, Default::normalizedRange);
|
||||
if (ccValue)
|
||||
resources.midiState.ccEvent(0, member.parameters.back(), *ccValue);
|
||||
initHdcc(member.parameters.back(), *ccValue);
|
||||
}
|
||||
break;
|
||||
case hash("label_cc&"):
|
||||
|
|
@ -1137,6 +1138,27 @@ void sfz::Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
|
|||
ccDispatch(delay, ccNumber, normValue);
|
||||
}
|
||||
|
||||
void sfz::Synth::initCc(int ccNumber, uint8_t ccValue) noexcept
|
||||
{
|
||||
const float normValue = normalizeCC(ccValue);
|
||||
initHdcc(ccNumber, normValue);
|
||||
}
|
||||
|
||||
void sfz::Synth::initHdcc(int ccNumber, float normValue) noexcept
|
||||
{
|
||||
ASSERT(ccNumber >= 0);
|
||||
ASSERT(ccNumber < config::numCCs);
|
||||
ccInitialValues[ccNumber] = normValue;
|
||||
resources.midiState.ccEvent(0, ccNumber, normValue);
|
||||
}
|
||||
|
||||
float sfz::Synth::getHdccInit(int ccNumber)
|
||||
{
|
||||
ASSERT(ccNumber >= 0);
|
||||
ASSERT(ccNumber < config::numCCs);
|
||||
return ccInitialValues[ccNumber];
|
||||
}
|
||||
|
||||
void sfz::Synth::pitchWheel(int delay, int pitch) noexcept
|
||||
{
|
||||
ASSERT(pitch <= 8192);
|
||||
|
|
|
|||
|
|
@ -370,6 +370,27 @@ public:
|
|||
*/
|
||||
void hdcc(int delay, int ccNumber, float normValue) noexcept;
|
||||
/**
|
||||
* @brief Set the initial value of a controller and send it to the synth
|
||||
*
|
||||
* @param ccNumber the cc number
|
||||
* @param ccValue the cc value
|
||||
*/
|
||||
void initCc(int ccNumber, uint8_t ccValue) noexcept;
|
||||
/**
|
||||
* @brief Set the initial value of a controller and send it to the synth
|
||||
*
|
||||
* @param ccNumber the cc number
|
||||
* @param normValue the normalized cc value, in domain 0 to 1
|
||||
*/
|
||||
void initHdcc(int ccNumber, float normValue) noexcept;
|
||||
/**
|
||||
* @brief Get the initial value of a controller under the current instrument
|
||||
*
|
||||
* @param ccNumber the cc number
|
||||
* @return the initial value
|
||||
*/
|
||||
float getHdccInit(int ccNumber);
|
||||
/**
|
||||
* @brief Send a pitch bend event to the synth
|
||||
*
|
||||
* @param delay the delay at which the event occurs; this should be lower
|
||||
|
|
@ -909,6 +930,9 @@ private:
|
|||
};
|
||||
SettingsPerVoice settingsPerVoice;
|
||||
|
||||
// Controller initial values
|
||||
std::array<float, config::numCCs> ccInitialValues;
|
||||
|
||||
Duration dispatchDuration { 0 };
|
||||
|
||||
Parser parser;
|
||||
|
|
|
|||
|
|
@ -1348,3 +1348,24 @@ TEST_CASE("[Synth] Off by with CC switches")
|
|||
REQUIRE( numPlayingVoices(synth) == 1 );
|
||||
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "*saw" );
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] Initial values of CC")
|
||||
{
|
||||
sfz::Synth synth;
|
||||
|
||||
synth.loadSfzString(fs::current_path() / "init_cc.sfz", R"(
|
||||
<region> sample=*sine
|
||||
)");
|
||||
|
||||
REQUIRE(synth.getHdccInit(111) == 0.0f);
|
||||
REQUIRE(synth.getHdccInit(7) == Approx(100.0f / 127)); // default volume
|
||||
REQUIRE(synth.getHdccInit(10) == 0.5f); // default pan
|
||||
|
||||
synth.loadSfzString(fs::current_path() / "init_cc.sfz", R"(
|
||||
<control> set_hdcc111=0.1234 set_cc112=77
|
||||
<region> sample=*sine
|
||||
)");
|
||||
|
||||
REQUIRE(synth.getHdccInit(111) == Approx(0.1234f));
|
||||
REQUIRE(synth.getHdccInit(112) == Approx(77.0f / 127));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue