Fix Sf2 player freezing on project unloading with shared SoundFonts (#6950)

* Require FluidSynth >= 1.1.7

* Use `fluid_sfont_t` directly without sharing

* Adjust formatting a bit
This commit is contained in:
Hyunjin Song
2023-11-18 21:27:09 +09:00
committed by GitHub
parent a64bbc7633
commit 1e2167d005
3 changed files with 20 additions and 85 deletions

View File

@@ -540,7 +540,7 @@ ENDIF()
# check for Fluidsynth
IF(WANT_SF2)
find_package(FluidSynth 1.1.0)
find_package(FluidSynth 1.1.7)
if(FluidSynth_FOUND)
SET(LMMS_HAVE_FLUIDSYNTH TRUE)
if(FluidSynth_VERSION_STRING VERSION_GREATER_EQUAL 2)

View File

@@ -121,12 +121,6 @@ struct Sf2PluginData
// Static map of current sfonts
QMap<QString, Sf2Font*> Sf2Instrument::s_fonts;
QMutex Sf2Instrument::s_fontsMutex;
Sf2Instrument::Sf2Instrument( InstrumentTrack * _instrument_track ) :
Instrument( _instrument_track, &sf2player_plugin_descriptor ),
m_srcState( nullptr ),
@@ -375,31 +369,12 @@ void Sf2Instrument::freeFont()
{
m_synthMutex.lock();
if ( m_font != nullptr )
if (m_font != nullptr)
{
s_fontsMutex.lock();
--(m_font->refCount);
// No more references
if( m_font->refCount <= 0 )
{
qDebug() << "Really deleting " << m_filename;
fluid_synth_sfunload( m_synth, m_fontId, true );
s_fonts.remove( m_filename );
delete m_font;
}
// Just remove our reference
else
{
qDebug() << "un-referencing " << m_filename;
fluid_synth_remove_sfont( m_synth, m_font->fluidFont );
}
s_fontsMutex.unlock();
fluid_synth_sfunload(m_synth, m_fontId, true);
m_font = nullptr;
}
m_synthMutex.unlock();
}
@@ -413,49 +388,29 @@ void Sf2Instrument::openFile( const QString & _sf2File, bool updateTrackName )
char * sf2Ascii = qstrdup( qPrintable( PathUtil::toAbsolute( _sf2File ) ) );
QString relativePath = PathUtil::toShortestRelative( _sf2File );
// free reference to soundfont if one is selected
// free the soundfont if one is selected
freeFont();
m_synthMutex.lock();
s_fontsMutex.lock();
// Increment Reference
if( s_fonts.contains( relativePath ) )
bool loaded = false;
if (fluid_is_soundfont(sf2Ascii))
{
qDebug() << "Using existing reference to " << relativePath;
m_fontId = fluid_synth_sfload(m_synth, sf2Ascii, true);
m_font = s_fonts[ relativePath ];
m_font->refCount++;
m_fontId = fluid_synth_add_sfont( m_synth, m_font->fluidFont );
}
// Add to map, if doesn't exist.
else
{
bool loaded = false;
if( fluid_is_soundfont( sf2Ascii ) )
if (fluid_synth_sfcount(m_synth) > 0)
{
m_fontId = fluid_synth_sfload( m_synth, sf2Ascii, true );
if( fluid_synth_sfcount( m_synth ) > 0 )
{
// Grab this sf from the top of the stack and add to list
m_font = new Sf2Font( fluid_synth_get_sfont( m_synth, 0 ) );
s_fonts.insert( relativePath, m_font );
loaded = true;
}
}
if(!loaded)
{
collectErrorForUI( Sf2Instrument::tr( "A soundfont %1 could not be loaded." ).
arg( QFileInfo( _sf2File ).baseName() ) );
// Grab this sf from the top of the stack and add to list
m_font = fluid_synth_get_sfont(m_synth, 0);
loaded = true;
}
}
s_fontsMutex.unlock();
if (!loaded)
{
collectErrorForUI(Sf2Instrument::tr("A soundfont %1 could not be loaded.").arg(QFileInfo(_sf2File).baseName()));
}
m_synthMutex.unlock();
if( m_fontId >= 0 )
@@ -627,12 +582,12 @@ void Sf2Instrument::reloadSynth()
{
// Now, delete the old one and replace
m_synthMutex.lock();
fluid_synth_remove_sfont( m_synth, m_font->fluidFont );
fluid_synth_remove_sfont( m_synth, m_font );
delete_fluid_synth( m_synth );
// New synth
m_synth = new_fluid_synth( m_settings );
m_fontId = fluid_synth_add_sfont( m_synth, m_font->fluidFont );
m_fontId = fluid_synth_add_sfont( m_synth, m_font );
m_synthMutex.unlock();
// synth program change (set bank and patch)

View File

@@ -114,16 +114,12 @@ public slots:
void updateTuning();
private:
static QMutex s_fontsMutex;
static QMap<QString, Sf2Font*> s_fonts;
static int (* s_origFree)( fluid_sfont_t * );
SRC_STATE * m_srcState;
fluid_settings_t* m_settings;
fluid_synth_t* m_synth;
Sf2Font* m_font;
fluid_sfont_t* m_font;
int m_fontId;
QString m_filename;
@@ -177,22 +173,6 @@ signals:
} ;
// A soundfont in our font-map
class Sf2Font
{
MM_OPERATORS
public:
Sf2Font( fluid_sfont_t * f ) :
fluidFont( f ),
refCount( 1 )
{};
fluid_sfont_t * fluidFont;
int refCount;
};
namespace gui
{