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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
|
||||
Reference in New Issue
Block a user