Merge pull request #421 from jpcima/cc-initial

Store the initial values of controllers
This commit is contained in:
JP Cimalando 2020-09-20 21:18:44 +02:00 committed by GitHub
commit 2f930d56af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 4 deletions

View file

@ -232,8 +232,9 @@ void sfz::Synth::clear()
modificationTime = fs::file_time_type::min(); modificationTime = fs::file_time_type::min();
// set default controllers // set default controllers
cc(0, 7, 100); // volume fill(absl::MakeSpan(ccInitialValues), 0.0f);
hdcc(0, 10, 0.5f); // pan initCc(7, 100); // volume
initHdcc(10, 0.5f); // pan
// set default controller labels // set default controller labels
insertPairUniquely(ccLabels, 7, "Volume"); insertPairUniquely(ccLabels, 7, "Volume");
@ -327,14 +328,14 @@ void sfz::Synth::handleControlOpcodes(const std::vector<Opcode>& members)
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) { if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
const auto ccValue = readOpcode(member.value, Default::midi7Range); const auto ccValue = readOpcode(member.value, Default::midi7Range);
if (ccValue) if (ccValue)
resources.midiState.ccEvent(0, member.parameters.back(), normalizeCC(*ccValue)); initCc(member.parameters.back(), *ccValue);
} }
break; break;
case hash("set_hdcc&"): case hash("set_hdcc&"):
if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) { if (Default::ccNumberRange.containsWithEnd(member.parameters.back())) {
const auto ccValue = readOpcode(member.value, Default::normalizedRange); const auto ccValue = readOpcode(member.value, Default::normalizedRange);
if (ccValue) if (ccValue)
resources.midiState.ccEvent(0, member.parameters.back(), *ccValue); initHdcc(member.parameters.back(), *ccValue);
} }
break; break;
case hash("label_cc&"): case hash("label_cc&"):
@ -1138,6 +1139,27 @@ void sfz::Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
ccDispatch(delay, ccNumber, normValue); 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 void sfz::Synth::pitchWheel(int delay, int pitch) noexcept
{ {
ASSERT(pitch <= 8192); ASSERT(pitch <= 8192);

View file

@ -369,7 +369,30 @@ public:
* @param normValue the normalized cc value, in domain 0 to 1 * @param normValue the normalized cc value, in domain 0 to 1
*/ */
void hdcc(int delay, int ccNumber, float normValue) noexcept; void hdcc(int delay, int ccNumber, float normValue) noexcept;
private:
/** /**
* @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;
public:
/**
* @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 * @brief Send a pitch bend event to the synth
* *
* @param delay the delay at which the event occurs; this should be lower * @param delay the delay at which the event occurs; this should be lower
@ -909,6 +932,9 @@ private:
}; };
SettingsPerVoice settingsPerVoice; SettingsPerVoice settingsPerVoice;
// Controller initial values
std::array<float, config::numCCs> ccInitialValues;
Duration dispatchDuration { 0 }; Duration dispatchDuration { 0 };
Parser parser; Parser parser;

View file

@ -1348,3 +1348,24 @@ TEST_CASE("[Synth] Off by with CC switches")
REQUIRE( numPlayingVoices(synth) == 1 ); REQUIRE( numPlayingVoices(synth) == 1 );
REQUIRE( getPlayingVoices(synth).front()->getRegion()->sampleId.filename() == "*saw" ); 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));
}