From 99791ddf251714ca675f5d8a92ab45a1f3070d43 Mon Sep 17 00:00:00 2001 From: Tobias Doerffel Date: Wed, 5 Aug 2009 18:00:04 +0200 Subject: [PATCH] Sf2Player: fixed crash and race conditions Do not crash if no fluid_voice could be determined in sf2Instrument::playNote() (which for example happens if no soundfont is loaded). Furthermore protect the FluidSynth API calls in the envelope and panning code with global synth mutex. (cherry picked from commit 144f0c6c80d88239314216df6ab88611187e8f57) --- plugins/sf2_player/sf2_player.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 0d33f7a45..f057e8cd8 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -613,10 +613,8 @@ void sf2Instrument::playNote( notePlayHandle * _n, sampleFrame * ) // get new voice and save it fluid_synth_get_voicelist( m_synth, voices, poly, -1 ); - int last = -1; for( int i = 0; i < poly && voices[i]; ++i ) { - last = i; const unsigned int newID = fluid_voice_get_id( voices[i] ); if( id[i] != newID || newID == 0 ) { @@ -624,10 +622,6 @@ void sf2Instrument::playNote( notePlayHandle * _n, sampleFrame * ) break; } } - if( pluginData->fluidVoice == NULL ) - { - pluginData->fluidVoice = voices[last]; - } m_synthMutex.unlock(); @@ -638,26 +632,33 @@ void sf2Instrument::playNote( notePlayHandle * _n, sampleFrame * ) SF2PluginData * pluginData = static_cast( _n->m_pluginData ); - if( pluginData->lastPanning != _n->getPanning() ) + if( pluginData->fluidVoice && + pluginData->lastPanning != _n->getPanning() ) { const float pan = -500 + ( (float)( _n->getPanning() - PanningLeft ) ) / ( (float)( PanningRight - PanningLeft ) ) * 1000; + + m_synthMutex.lock(); fluid_voice_gen_set( pluginData->fluidVoice, GEN_PAN, pan ); fluid_voice_update_param( pluginData->fluidVoice, GEN_PAN ); + m_synthMutex.unlock(); pluginData->lastPanning = _n->getPanning(); } const float currentVelocity = _n->volumeLevel( tfp ) * 127; - if( pluginData->lastVelocity != currentVelocity ) + if( pluginData->fluidVoice && + pluginData->lastVelocity != currentVelocity ) { + m_synthMutex.lock(); fluid_voice_gen_set( pluginData->fluidVoice, GEN_VELOCITY, currentVelocity ); fluid_voice_update_param( pluginData->fluidVoice, GEN_VELOCITY ); // make sure, FluidSynth modulates our changed GEN_VELOCITY via internal // attenuation modulator, so changes take effect (7=Volume CC) fluid_synth_cc( m_synth, m_channel, 7, 127 ); + m_synthMutex.unlock(); pluginData->lastVelocity = currentVelocity; }