diff --git a/src/sfizz/Config.h b/src/sfizz/Config.h index c13707ef..2956dae6 100644 --- a/src/sfizz/Config.h +++ b/src/sfizz/Config.h @@ -103,10 +103,14 @@ namespace config { // Wavetable constants; amplitude values are matched to reference static constexpr unsigned tableSize = 1024; static constexpr double tableRefSampleRate = 44100.0 * 1.1; // +10% aliasing permissivity - static constexpr double amplitudeSine = 0.625; - static constexpr double amplitudeTriangle = 0.625; - static constexpr double amplitudeSaw = 0.515; - static constexpr double amplitudeSquare = 0.515; + /** + Default wave amplitudes, adjusted for consistent RMS among all waves. + (except square curiously, but it's to match ARIA) + */ + static constexpr double amplitudeSine = 1.0; + static constexpr double amplitudeTriangle = 1.0; + static constexpr double amplitudeSaw = 0.8164965809277261; // sqrt(2)/sqrt(3) + static constexpr double amplitudeSquare = 0.8164965809277261; // should have been sqrt(2)? /** Background file loading */ diff --git a/src/sfizz/Synth.cpp b/src/sfizz/Synth.cpp index dcbffc6f..0ce7d527 100644 --- a/src/sfizz/Synth.cpp +++ b/src/sfizz/Synth.cpp @@ -143,6 +143,16 @@ void sfz::Synth::buildRegion(const std::vector& regionOpcodes) int regionNumber = static_cast(regions.size()); auto lastRegion = absl::make_unique(regionNumber, resources.midiState, defaultPath); + // Create default connections + constexpr unsigned defaultSmoothness = 10; + lastRegion->getOrCreateConnection( + ModKey::createCC(7, 4, defaultSmoothness, 100, 0), + ModKey::createNXYZ(ModId::Amplitude, lastRegion->id)); + lastRegion->getOrCreateConnection( + ModKey::createCC(10, 1, defaultSmoothness, 100, 0), + ModKey::createNXYZ(ModId::Pan, lastRegion->id)); + + // auto parseOpcodes = [&](const std::vector& opcodes) { for (auto& opcode : opcodes) { const auto unknown = absl::c_find_if(unknownOpcodes, [&](absl::string_view sv) { return sv.compare(opcode.opcode) == 0; }); @@ -215,6 +225,10 @@ void sfz::Synth::clear() polyphonyGroups.emplace_back(); polyphonyGroups.back().setPolyphonyLimit(config::maxVoices); modificationTime = fs::file_time_type::min(); + + // set default controllers + cc(0, 7, 100); // volume + hdcc(0, 10, 0.5f); // pan } void sfz::Synth::handleMasterOpcodes(const std::vector& members) diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 331ae748..d7517a3d 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -491,6 +491,10 @@ void sfz::Voice::panStageStereo(AudioSpan buffer) noexcept (*modulationSpan)[i] += normalizePercents(mod[i]); } pan(*modulationSpan, leftBuffer, rightBuffer); + + // add +3dB to compensate for the 2 pan stages (-3dB each stage) + applyGain1(1.4125375446227544f, leftBuffer); + applyGain1(1.4125375446227544f, rightBuffer); } void sfz::Voice::filterStageMono(AudioSpan buffer) noexcept