Add ability to override gain per-SoundFont

Closes #248.
This commit is contained in:
Dale Whinham
2022-03-03 16:23:17 +00:00
parent 164174aab4
commit a19f6c6015
8 changed files with 29 additions and 27 deletions

View File

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

View File

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

View File

@@ -27,6 +27,8 @@
struct TFXProfile
{
TOptional<float> nGain;
TOptional<bool> bReverbActive;
TOptional<float> nReverbDamping;
TOptional<float> nReverbLevel;

View File

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

View File

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

View File

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

View File

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

View File

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