From 144f0c6c80d88239314216df6ab88611187e8f57 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. --- plugins/sf2_player/sf2_player.cpp | 18 +++++++++--------- plugins/sf2_player/sf2_player.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/sf2_player/sf2_player.cpp b/plugins/sf2_player/sf2_player.cpp index 2d0ed310f..0297fda75 100644 --- a/plugins/sf2_player/sf2_player.cpp +++ b/plugins/sf2_player/sf2_player.cpp @@ -43,7 +43,6 @@ #include "patches_dialog.h" #include "tooltip.h" #include "lcd_spinbox.h" -#include "panning.h" #include "embed.cpp" @@ -616,10 +615,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 ) { @@ -627,10 +624,6 @@ void sf2Instrument::playNote( notePlayHandle * _n, sampleFrame * ) break; } } - if( pluginData->fluidVoice == NULL ) - { - pluginData->fluidVoice = voices[last]; - } m_synthMutex.unlock(); @@ -641,26 +634,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; } diff --git a/plugins/sf2_player/sf2_player.h b/plugins/sf2_player/sf2_player.h index 8f84c344f..30630b2d0 100644 --- a/plugins/sf2_player/sf2_player.h +++ b/plugins/sf2_player/sf2_player.h @@ -62,7 +62,7 @@ public: virtual void playNote( notePlayHandle * _n, sampleFrame * _working_buffer ); virtual void deleteNotePluginData( notePlayHandle * _n ); - + virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); virtual void loadSettings( const QDomElement & _this );