diff --git a/CHANGELOG.md b/CHANGELOG.md index a508ac3..7fc9cbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * This update adds support for MT-32 ROM versions 2.06, 2.07 and CM-32LN ROM version 1.00 (CM-32LN is untested). - Update to FluidSynth v2.2.5. - MT-32 LCD emulation replaced with new libmt32emu v2.6+ display emulation. +- FluidSynth's master volume gain is now an effects profile setting and can be overridden on a per-SoundFont basis (issue #248). Thanks to @c0d3h4x0r for the suggestion! ### Fixed diff --git a/include/config.def b/include/config.def index a70c2ff..0974cfc 100644 --- a/include/config.def +++ b/include/config.def @@ -76,8 +76,8 @@ END_SECTION BEGIN_SECTION(fluidsynth) CFG(soundfont, int, FluidSynthSoundFont, 0 ) -CFG(gain, float, FluidSynthGain, 0.2f ) CFG(polyphony, int, FluidSynthPolyphony, 200 ) +CFG(gain, float, FluidSynthDefaultGain, 0.2f ) CFG(reverb, bool, FluidSynthDefaultReverbActive, true ) CFG(reverb_damping, float, FluidSynthDefaultReverbDamping, 0.0 ) CFG(reverb_level, float, FluidSynthDefaultReverbLevel, 0.9 ) diff --git a/include/synth/fxprofile.h b/include/synth/fxprofile.h index 39e1a48..c16424d 100644 --- a/include/synth/fxprofile.h +++ b/include/synth/fxprofile.h @@ -27,6 +27,8 @@ struct TFXProfile { + TOptional nGain; + TOptional bReverbActive; TOptional nReverbDamping; TOptional nReverbLevel; diff --git a/include/synth/soundfontsynth.h b/include/synth/soundfontsynth.h index a1393b3..a4f75c1 100644 --- a/include/synth/soundfontsynth.h +++ b/include/synth/soundfontsynth.h @@ -34,7 +34,7 @@ class CSoundFontSynth : public CSynthBase { public: - CSoundFontSynth(unsigned nSampleRate, float nGain = 0.2f, u32 nPolyphony = 256); + CSoundFontSynth(unsigned nSampleRate); virtual ~CSoundFontSynth() override; // CSynthBase @@ -66,10 +66,9 @@ private: fluid_settings_t* m_pSettings; fluid_synth_t* m_pSynth; + u8 m_nVolume; float m_nInitialGain; - float m_nCurrentGain; - u32 m_nPolyphony; u16 m_nPercussionMask; size_t m_nCurrentSoundFontIndex; diff --git a/sdcard/mt32-pi.cfg b/sdcard/mt32-pi.cfg index 184211d..8626f58 100644 --- a/sdcard/mt32-pi.cfg +++ b/sdcard/mt32-pi.cfg @@ -302,17 +302,6 @@ reversed_stereo = off # Values: 0-255 (0*) soundfont = 0 -# Set the master volume gain. -# -# The default is a low value to avoid clipping when many notes are playing at -# once. -# -# The value should be a decimal value between 0.0 and 10.0. Values outside this -# range will be clamped. -# -# Values: 0.0-10.0 (0.2*) -gain = 0.2 - # Set the maximum number of voices that can be played simultaneously. # # Depending on the complexity of your SoundFont, you may need to reduce this @@ -329,8 +318,8 @@ gain = 0.2 # Values: 1-65535 (200*) polyphony = 200 -# The following settings set the default parameters for FluidSynth's reverb and -# chorus effects. +# The following settings set the default parameters for FluidSynth's master +# volume gain, reverb and chorus effects. # # Each setting can be overridden on a per-SoundFont basis by adding extra # sections, e.g. [fluidsynth.soundfont.x], where x is the zero-based index of @@ -338,6 +327,8 @@ polyphony = 200 # # Full descriptions and valid value ranges for each setting can be found in the # FluidSynth documentation: https://www.fluidsynth.org/api/fluidsettings.xml +gain = 0.2 + reverb = on reverb_damping = 0.0 reverb_level = 0.9 @@ -356,6 +347,8 @@ chorus_speed = 0.3 [fluidsynth.soundfont.0] # The following settings are recommended for GeneralUser GS by its author. +gain = 0.2 + reverb = on reverb_damping = 0.19 reverb_level = 0.5 diff --git a/src/config.cpp b/src/config.cpp index b82abfd..5182547 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -145,6 +145,8 @@ bool CConfig::ParseFXProfileOption(const char* pString, const char* pValue, TFXP return false; \ } + MATCH("gain", float, nGain); + MATCH("reverb", bool, bReverbActive); MATCH("reverb_damping", float, nReverbDamping); MATCH("reverb_level", float, nReverbLevel); diff --git a/src/mt32pi.cpp b/src/mt32pi.cpp index 608fa2f..e9af315 100644 --- a/src/mt32pi.cpp +++ b/src/mt32pi.cpp @@ -392,7 +392,7 @@ bool CMT32Pi::InitSoundFontSynth() { assert(m_pSoundFontSynth == nullptr); - m_pSoundFontSynth = new CSoundFontSynth(m_pConfig->AudioSampleRate, m_pConfig->FluidSynthGain, m_pConfig->FluidSynthPolyphony); + m_pSoundFontSynth = new CSoundFontSynth(m_pConfig->AudioSampleRate); if (!m_pSoundFontSynth->Initialize()) { m_pLogger->Write(MT32PiName, LogWarning, "FluidSynth init failed; no SoundFonts present?"); diff --git a/src/synth/soundfontsynth.cpp b/src/synth/soundfontsynth.cpp index 09321ea..4349f2b 100644 --- a/src/synth/soundfontsynth.cpp +++ b/src/synth/soundfontsynth.cpp @@ -129,16 +129,15 @@ extern "C" } } -CSoundFontSynth::CSoundFontSynth(unsigned nSampleRate, float nGain, u32 nPolyphony) +CSoundFontSynth::CSoundFontSynth(unsigned nSampleRate) : CSynthBase(nSampleRate), m_pSettings(nullptr), m_pSynth(nullptr), - m_nInitialGain(nGain), - m_nCurrentGain(nGain), + m_nVolume(100), + m_nInitialGain(0.2f), - m_nPolyphony(nPolyphony), m_nPercussionMask(1 << 9), m_nCurrentSoundFontIndex(0) { @@ -298,9 +297,9 @@ void CSoundFontSynth::AllSoundOff() void CSoundFontSynth::SetMasterVolume(u8 nVolume) { - m_nCurrentGain = nVolume / 100.0f * m_nInitialGain; + m_nVolume = nVolume; m_Lock.Acquire(); - fluid_synth_set_gain(m_pSynth, m_nCurrentGain); + fluid_synth_set_gain(m_pSynth, m_nVolume / 100.0f * m_nInitialGain); m_Lock.Release(); } @@ -393,8 +392,10 @@ bool CSoundFontSynth::Reinitialize(const char* pSoundFontPath, const TFXProfile* return false; } - fluid_synth_set_gain(m_pSynth, m_nCurrentGain); - fluid_synth_set_polyphony(m_pSynth, m_nPolyphony); + fluid_synth_set_polyphony(m_pSynth, pConfig->FluidSynthPolyphony); + + m_nInitialGain = pFXProfile->nGain.ValueOr(pConfig->FluidSynthDefaultGain); + fluid_synth_set_gain(m_pSynth, m_nVolume / 100.0f * m_nInitialGain); // Use values from effects profile if set, otherwise use defaults fluid_synth_reverb_on(m_pSynth, -1, pFXProfile->bReverbActive.ValueOr(pConfig->FluidSynthDefaultReverbActive)); @@ -442,9 +443,11 @@ void CSoundFontSynth::ResetMIDIMonitor() void CSoundFontSynth::DumpFXSettings() const { CLogger* const pLogger = CLogger::Get(); - double nReverbDamping, nReverbLevel, nReverbRoomSize, nReverbWidth, nChorusDepth, nChorusLevel, nChorusSpeed; + double nGain, nReverbDamping, nReverbLevel, nReverbRoomSize, nReverbWidth, nChorusDepth, nChorusLevel, nChorusSpeed; int nChorusVoices; + nGain = fluid_synth_get_gain(m_pSynth); + assert(fluid_synth_get_reverb_group_damp(m_pSynth, -1, &nReverbDamping) == FLUID_OK); assert(fluid_synth_get_reverb_group_level(m_pSynth, -1, &nReverbLevel) == FLUID_OK); assert(fluid_synth_get_reverb_group_roomsize(m_pSynth, -1, &nReverbRoomSize) == FLUID_OK); @@ -455,6 +458,8 @@ void CSoundFontSynth::DumpFXSettings() const assert(fluid_synth_get_chorus_group_nr(m_pSynth, -1, &nChorusVoices) == FLUID_OK); assert(fluid_synth_get_chorus_group_speed(m_pSynth, -1, &nChorusSpeed) == FLUID_OK); + pLogger->Write(SoundFontSynthName, LogNotice, "Gain: %.2f", nGain); + pLogger->Write(SoundFontSynthName, LogNotice, "Reverb: %.2f, %.2f, %.2f, %.2f", nReverbDamping,