Skip to content

Commit

Permalink
Add ability to override gain per-SoundFont
Browse files Browse the repository at this point in the history
Closes #248.
  • Loading branch information
dwhinham committed Mar 4, 2022
1 parent ae30e8d commit dc01c39
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 27 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

- Update to FluidSynth v2.2.5.
- 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

Expand Down
2 changes: 1 addition & 1 deletion include/config.def
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
Expand Down
2 changes: 2 additions & 0 deletions include/synth/fxprofile.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

struct TFXProfile
{
TOptional<float> nGain;

TOptional<bool> bReverbActive;
TOptional<float> nReverbDamping;
TOptional<float> nReverbLevel;
Expand Down
5 changes: 2 additions & 3 deletions include/synth/soundfontsynth.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -66,10 +66,9 @@ class CSoundFontSynth : public CSynthBase
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;

Expand Down
19 changes: 6 additions & 13 deletions sdcard/mt32-pi.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -329,15 +318,17 @@ 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
# voluime 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
# the SoundFont. See the next section for an example.
#
# 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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,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);
Expand Down
2 changes: 1 addition & 1 deletion src/mt32pi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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?");
Expand Down
23 changes: 14 additions & 9 deletions src/synth/soundfontsynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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();
}

Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand All @@ -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,
Expand Down

0 comments on commit dc01c39

Please sign in to comment.