Skip to content

Commit

Permalink
Merge pull request #2497 from Fastigium/preview-fix
Browse files Browse the repository at this point in the history
Fix crashes/hangs when previewing instrument presets
  • Loading branch information
tresf committed Feb 16, 2016
2 parents 8841b89 + 9d1867c commit 47606d7
Show file tree
Hide file tree
Showing 14 changed files with 64 additions and 19 deletions.
2 changes: 1 addition & 1 deletion include/Mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ class EXPORT Mixer : public QObject
return m_playHandles;
}

void removePlayHandles( Track * _track, bool removeIPHs = true );
void removePlayHandlesOfTypes( Track * _track, const quint8 types );

bool hasNotePlayHandles();

Expand Down
9 changes: 4 additions & 5 deletions include/PlayHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ class PlayHandle : public ThreadableJob
public:
enum Types
{
TypeNotePlayHandle,
TypeInstrumentPlayHandle,
TypeSamplePlayHandle,
TypePresetPreviewHandle,
TypeCount
TypeNotePlayHandle = 0x01,
TypeInstrumentPlayHandle = 0x02,
TypeSamplePlayHandle = 0x04,
TypePresetPreviewHandle = 0x08
} ;
typedef Types Type;

Expand Down
5 changes: 5 additions & 0 deletions include/PresetPreviewPlayHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ class EXPORT PresetPreviewPlayHandle : public PlayHandle
PresetPreviewPlayHandle( const QString& presetFile, bool loadByPlugin = false, DataFile *dataFile = 0 );
virtual ~PresetPreviewPlayHandle();

virtual inline bool affinityMatters() const
{
return true;
}

virtual void play( sampleFrame* buffer );
virtual bool isFinished() const;

Expand Down
4 changes: 3 additions & 1 deletion plugins/GigPlayer/GigPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ GigInstrument::GigInstrument( InstrumentTrack * _instrument_track ) :

GigInstrument::~GigInstrument()
{
Engine::mixer()->removePlayHandles( instrumentTrack() );
Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle );
freeInstance();
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/carlabase/carla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ CarlaInstrument::CarlaInstrument(InstrumentTrack* const instrumentTrack, const D

CarlaInstrument::~CarlaInstrument()
{
Engine::mixer()->removePlayHandles( instrumentTrack() );
Engine::mixer()->removePlayHandlesOfTypes(instrumentTrack(), PlayHandle::TypeNotePlayHandle | PlayHandle::TypeInstrumentPlayHandle);

if (fHost.resourceDir != NULL)
{
Expand Down
4 changes: 3 additions & 1 deletion plugins/opl2/opl2instrument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ opl2instrument::opl2instrument( InstrumentTrack * _instrument_track ) :

opl2instrument::~opl2instrument() {
delete theEmulator;
Engine::mixer()->removePlayHandles( instrumentTrack() );
Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle );
delete [] renderbuffer;
}

Expand Down
4 changes: 3 additions & 1 deletion plugins/sf2_player/sf2_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) :

sf2Instrument::~sf2Instrument()
{
Engine::mixer()->removePlayHandles( instrumentTrack() );
Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle );
freeFont();
delete_fluid_synth( m_synth );
delete_fluid_settings( m_settings );
Expand Down
4 changes: 3 additions & 1 deletion plugins/vestige/vestige.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ vestigeInstrument::~vestigeInstrument()
knobFModel = NULL;
}

Engine::mixer()->removePlayHandles( instrumentTrack() );
Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle );
closePlugin();
}

Expand Down
4 changes: 3 additions & 1 deletion plugins/zynaddsubfx/ZynAddSubFx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ ZynAddSubFxInstrument::ZynAddSubFxInstrument(

ZynAddSubFxInstrument::~ZynAddSubFxInstrument()
{
Engine::mixer()->removePlayHandles( instrumentTrack() );
Engine::mixer()->removePlayHandlesOfTypes( instrumentTrack(),
PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle );

m_pluginMutex.lock();
delete m_plugin;
Expand Down
6 changes: 6 additions & 0 deletions src/core/EffectChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void EffectChain::loadSettings( const QDomElement & _this )
{
clear();

// TODO This method should probably also lock the mixer

m_enabledModel.setValue( _this.attribute( "enabled" ).toInt() );

const int plugin_cnt = _this.attribute( "numofeffects" ).toInt();
Expand Down Expand Up @@ -264,10 +266,14 @@ void EffectChain::clear()
{
emit aboutToClear();

Engine::mixer()->lock();

m_enabledModel.setValue( false );
for( int i = 0; i < m_effects.count(); ++i )
{
delete m_effects[i];
}
m_effects.clear();

Engine::mixer()->unlock();
}
28 changes: 24 additions & 4 deletions src/core/Mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,12 +642,32 @@ void Mixer::removePlayHandle( PlayHandle * _ph )
{
lockPlayHandleRemoval();
_ph->audioPort()->removePlayHandle( _ph );
bool removedFromList = false;
// Check m_newPlayHandles first because doing it the other way around
// creates a race condition
m_playHandleMutex.lock();
PlayHandleList::Iterator it =
qFind( m_playHandles.begin(),
m_playHandles.end(), _ph );
qFind( m_newPlayHandles.begin(),
m_newPlayHandles.end(), _ph );
if( it != m_newPlayHandles.end() )
{
m_newPlayHandles.erase( it );
removedFromList = true;
}
m_playHandleMutex.unlock();
// Now check m_playHandles
it = qFind( m_playHandles.begin(),
m_playHandles.end(), _ph );
if( it != m_playHandles.end() )
{
m_playHandles.erase( it );
removedFromList = true;
}
// Only deleting PlayHandles that were actually found in the list
// "fixes crash when previewing a preset under high load"
// (See tobydox's 2008 commit 4583e48)
if ( removedFromList )
{
if( _ph->type() == PlayHandle::TypeNotePlayHandle )
{
NotePlayHandleManager::release( (NotePlayHandle*) _ph );
Expand All @@ -665,13 +685,13 @@ void Mixer::removePlayHandle( PlayHandle * _ph )



void Mixer::removePlayHandles( Track * _track, bool removeIPHs )
void Mixer::removePlayHandlesOfTypes( Track * _track, const quint8 types )
{
lockPlayHandleRemoval();
PlayHandleList::Iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
{
if( ( *it )->isFromTrack( _track ) && ( removeIPHs || ( *it )->type() != PlayHandle::TypeInstrumentPlayHandle ) )
if( ( *it )->isFromTrack( _track ) && ( ( *it )->type() & types ) )
{
( *it )->audioPort()->removePlayHandle( ( *it ) );
if( ( *it )->type() == PlayHandle::TypeNotePlayHandle )
Expand Down
4 changes: 3 additions & 1 deletion src/tracks/BBTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,9 @@ BBTrack::BBTrack( TrackContainer* tc ) :

BBTrack::~BBTrack()
{
Engine::mixer()->removePlayHandles( this );
Engine::mixer()->removePlayHandlesOfTypes( this,
PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle );

const int bb = s_infoMap[this];
Engine::getBBTrackContainer()->removeBB( bb );
Expand Down
5 changes: 4 additions & 1 deletion src/tracks/InstrumentTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,10 @@ void InstrumentTrack::silenceAllNotes( bool removeIPH )
lock();
// invalidate all NotePlayHandles linked to this track
m_processHandles.clear();
Engine::mixer()->removePlayHandles( this, removeIPH );
Engine::mixer()->removePlayHandlesOfTypes( this, removeIPH
? PlayHandle::TypeNotePlayHandle
| PlayHandle::TypeInstrumentPlayHandle
: PlayHandle::TypeNotePlayHandle );
unlock();
}

Expand Down
2 changes: 1 addition & 1 deletion src/tracks/SampleTrack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ SampleTrack::SampleTrack( TrackContainer* tc ) :

SampleTrack::~SampleTrack()
{
Engine::mixer()->removePlayHandles( this );
Engine::mixer()->removePlayHandlesOfTypes( this, PlayHandle::TypeSamplePlayHandle );
}


Expand Down

0 comments on commit 47606d7

Please sign in to comment.