Support multi-level volumes
This commit is contained in:
parent
95bf4fc480
commit
bf8b3fd111
3 changed files with 78 additions and 1 deletions
|
|
@ -539,6 +539,27 @@ bool sfz::Region::parseOpcode(const Opcode& rawOpcode)
|
|||
case hash("rt_decay"):
|
||||
setValueFromOpcode(opcode, rtDecay, Default::rtDecayRange);
|
||||
break;
|
||||
case hash("global_amplitude"):
|
||||
if (auto value = readOpcode(opcode.value, Default::amplitudeRange))
|
||||
globalAmplitude = normalizePercents(*value);
|
||||
break;
|
||||
case hash("master_amplitude"):
|
||||
if (auto value = readOpcode(opcode.value, Default::amplitudeRange))
|
||||
masterAmplitude = normalizePercents(*value);
|
||||
break;
|
||||
case hash("group_amplitude"):
|
||||
if (auto value = readOpcode(opcode.value, Default::amplitudeRange))
|
||||
groupAmplitude = normalizePercents(*value);
|
||||
break;
|
||||
case hash("global_volume"):
|
||||
setValueFromOpcode(opcode, globalVolume, Default::volumeRange);
|
||||
break;
|
||||
case hash("master_volume"):
|
||||
setValueFromOpcode(opcode, masterVolume, Default::volumeRange);
|
||||
break;
|
||||
case hash("group_volume"):
|
||||
setValueFromOpcode(opcode, groupVolume, Default::volumeRange);
|
||||
break;
|
||||
|
||||
// Performance parameters: filters
|
||||
case hash("cutoff&"): // also cutoff
|
||||
|
|
@ -1165,6 +1186,9 @@ float sfz::Region::getBaseVolumedB(int noteNumber) const noexcept
|
|||
{
|
||||
fast_real_distribution<float> volumeDistribution { -ampRandom, ampRandom };
|
||||
auto baseVolumedB = volume + volumeDistribution(Random::randomGenerator);
|
||||
baseVolumedB += globalVolume;
|
||||
baseVolumedB += masterVolume;
|
||||
baseVolumedB += groupVolume;
|
||||
if (trigger == SfzTrigger::release || trigger == SfzTrigger::release_key)
|
||||
baseVolumedB -= rtDecay * midiState.getNoteDuration(noteNumber);
|
||||
return baseVolumedB;
|
||||
|
|
@ -1172,7 +1196,13 @@ float sfz::Region::getBaseVolumedB(int noteNumber) const noexcept
|
|||
|
||||
float sfz::Region::getBaseGain() const noexcept
|
||||
{
|
||||
return amplitude;
|
||||
float baseGain = amplitude;
|
||||
|
||||
baseGain *= globalAmplitude;
|
||||
baseGain *= masterAmplitude;
|
||||
baseGain *= groupAmplitude;
|
||||
|
||||
return baseGain;
|
||||
}
|
||||
|
||||
float sfz::Region::getPhase() const noexcept
|
||||
|
|
|
|||
|
|
@ -345,6 +345,13 @@ struct Region {
|
|||
CCMap<Range<float>> crossfadeCCOutRange { Default::crossfadeCCOutRange }; // xfout_loccN xfout_hiccN
|
||||
float rtDecay { Default::rtDecay }; // rt_decay
|
||||
|
||||
float globalAmplitude { 1.0 }; // global_amplitude
|
||||
float masterAmplitude { 1.0 }; // master_amplitude
|
||||
float groupAmplitude { 1.0 }; // group_amplitude
|
||||
float globalVolume { 0.0 }; // global_volume
|
||||
float masterVolume { 0.0 }; // master_volume
|
||||
float groupVolume { 0.0 }; // group_volume
|
||||
|
||||
// Filters and EQs
|
||||
std::vector<EQDescription> equalizers;
|
||||
std::vector<FilterDescription> filters;
|
||||
|
|
|
|||
|
|
@ -882,6 +882,46 @@ TEST_CASE("[Region] Parsing opcodes")
|
|||
REQUIRE(region.crossfadeCCCurve == SfzCrossfadeCurve::gain);
|
||||
}
|
||||
|
||||
SECTION("*_volume")
|
||||
{
|
||||
const std::pair<absl::string_view, float*> assoc_pairs[] = {
|
||||
{"global_volume", ®ion.globalVolume},
|
||||
{"master_volume", ®ion.masterVolume},
|
||||
{"group_volume", ®ion.groupVolume},
|
||||
};
|
||||
for (auto a : assoc_pairs) {
|
||||
REQUIRE(region.volume == 0.0f);
|
||||
region.parseOpcode({ a.first, "4.2" });
|
||||
REQUIRE(*a.second == 4.2f);
|
||||
region.parseOpcode({ a.first, "-4.2" });
|
||||
REQUIRE(*a.second == -4.2f);
|
||||
region.parseOpcode({ a.first, "-123" });
|
||||
REQUIRE(*a.second == -123.0f);
|
||||
region.parseOpcode({ a.first, "-185" });
|
||||
REQUIRE(*a.second == -144.0f);
|
||||
region.parseOpcode({ a.first, "79" });
|
||||
REQUIRE(*a.second == 48.0f);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("*_amplitude")
|
||||
{
|
||||
const std::pair<absl::string_view, float*> assoc_pairs[] = {
|
||||
{"global_amplitude", ®ion.globalAmplitude},
|
||||
{"master_amplitude", ®ion.masterAmplitude},
|
||||
{"group_amplitude", ®ion.groupAmplitude},
|
||||
};
|
||||
for (auto a : assoc_pairs) {
|
||||
REQUIRE(*a.second == 1.0_a);
|
||||
region.parseOpcode({ a.first, "40" });
|
||||
REQUIRE(*a.second == 0.4_a);
|
||||
region.parseOpcode({ a.first, "-40" });
|
||||
REQUIRE(*a.second == 0_a);
|
||||
region.parseOpcode({ a.first, "140" });
|
||||
REQUIRE(*a.second == 1.0_a);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pitch_keycenter")
|
||||
{
|
||||
REQUIRE(region.pitchKeycenter == 60);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue