Store the initial values of controllers

This commit is contained in:
Jean Pierre Cimalando 2020-09-16 14:45:32 +02:00
parent f0dd146361
commit 3cf7536c57
3 changed files with 71 additions and 4 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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));
}