From ab107f01f983a9f9f9824a4686fc92d41aae6605 Mon Sep 17 00:00:00 2001 From: akimaze <63190361+akimaze@users.noreply.github.com> Date: Sat, 9 May 2020 06:23:40 +0200 Subject: [PATCH] VST preset preview (#5441) * Enable vestige presets preview. * Don't destroy vestige instrument on every preset change. * Don't reload VST dll plugin when it's not necessary. Always hide plugin UI in preview mode. * Don't remove other instruments in preview mode, don't send instrument change signal. * Minor changes * Add a change I missed Co-authored-by: Hyunjin Song --- include/InstrumentTrack.h | 7 ++++ plugins/vestige/vestige.cpp | 28 +++++++++++---- src/core/PresetPreviewPlayHandle.cpp | 16 ++------- src/tracks/InstrumentTrack.cpp | 51 ++++++++++++++++++++-------- 4 files changed, 68 insertions(+), 34 deletions(-) diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h index f2602686b..b30d5cb21 100644 --- a/include/InstrumentTrack.h +++ b/include/InstrumentTrack.h @@ -214,6 +214,10 @@ public: void setPreviewMode( const bool ); + bool isPreviewMode() const + { + return m_previewMode; + } signals: void instrumentChanged(); @@ -230,6 +234,9 @@ protected: return "instrumenttrack"; } + // get the name of the instrument in the saved data + QString getSavedInstrumentName(const QDomElement & thisElement) const; + protected slots: void updateBaseNote(); diff --git a/plugins/vestige/vestige.cpp b/plugins/vestige/vestige.cpp index fc61a2484..9efd3c97b 100644 --- a/plugins/vestige/vestige.cpp +++ b/plugins/vestige/vestige.cpp @@ -198,9 +198,15 @@ void vestigeInstrument::loadSettings( const QDomElement & _this ) { m_plugin->loadSettings( _this ); - if ( _this.attribute( "guivisible" ).toInt() ) { + if (instrumentTrack() != NULL && instrumentTrack()->isPreviewMode()) + { + m_plugin->hideUI(); + } + else if (_this.attribute( "guivisible" ).toInt()) + { m_plugin->showUI(); - } else { + } else + { m_plugin->hideUI(); } @@ -322,12 +328,17 @@ void vestigeInstrument::loadFile( const QString & _file ) { m_pluginMutex.lock(); const bool set_ch_name = ( m_plugin != NULL && - instrumentTrack()->name() == m_plugin->name() ) || - instrumentTrack()->name() == InstrumentTrack::tr( "Default preset" ) || - instrumentTrack()->name() == displayName(); + instrumentTrack()->name() == m_plugin->name() ) || + instrumentTrack()->name() == InstrumentTrack::tr( "Default preset" ) || + instrumentTrack()->name() == displayName(); m_pluginMutex.unlock(); + // if the same is loaded don't load again (for preview) + if (instrumentTrack() != NULL && instrumentTrack()->isPreviewMode() && + m_pluginDLL == SampleBuffer::tryToMakeRelative( _file )) + return; + if ( m_plugin != NULL ) { closePlugin(); @@ -354,8 +365,11 @@ void vestigeInstrument::loadFile( const QString & _file ) return; } - m_plugin->createUI(nullptr); - m_plugin->showUI(); + if ( !(instrumentTrack() != NULL && instrumentTrack()->isPreviewMode())) + { + m_plugin->createUI(nullptr); + m_plugin->showUI(); + } if( set_ch_name ) { diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index 11b145b22..d7a0260ef 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -156,19 +156,9 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, dataFileCreated = true; } - // vestige previews are bug prone; fallback on 3xosc with volume of 0 - // without an instrument in preview track, it will segfault - if(dataFile->content().elementsByTagName( "vestige" ).length() == 0 ) - { - s_previewTC->previewInstrumentTrack()-> - loadTrackSpecificSettings( - dataFile->content().firstChild().toElement() ); - } - else - { - s_previewTC->previewInstrumentTrack()->loadInstrument("tripleoscillator"); - s_previewTC->previewInstrumentTrack()->setVolume( 0 ); - } + s_previewTC->previewInstrumentTrack()->loadTrackSpecificSettings( + dataFile->content().firstChild().toElement()); + if( dataFileCreated ) { delete dataFile; diff --git a/src/tracks/InstrumentTrack.cpp b/src/tracks/InstrumentTrack.cpp index 52fb1044a..18dcdf81a 100644 --- a/src/tracks/InstrumentTrack.cpp +++ b/src/tracks/InstrumentTrack.cpp @@ -771,7 +771,11 @@ void InstrumentTrack::saveTrackSpecificSettings( QDomDocument& doc, QDomElement void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement ) { - silenceAllNotes( true ); + // don't delete instrument in preview mode if it's the same + // we can't do this for other situations due to some issues with linked models + bool reuseInstrument = m_previewMode && m_instrument && m_instrument->nodeName() == getSavedInstrumentName(thisElement); + // remove the InstrumentPlayHandle if and only if we need to delete the instrument + silenceAllNotes(!reuseInstrument); lock(); @@ -815,33 +819,39 @@ void InstrumentTrack::loadTrackSpecificSettings( const QDomElement & thisElement { m_audioPort.effects()->restoreState( node.toElement() ); } - else if( node.nodeName() == "instrument" ) + else if(node.nodeName() == "instrument") { typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey; - PluginKey key( node.toElement().elementsByTagName( "key" ).item( 0 ).toElement() ); + PluginKey key(node.toElement().elementsByTagName("key").item(0).toElement()); - delete m_instrument; - m_instrument = NULL; - m_instrument = Instrument::instantiate( - node.toElement().attribute( "name" ), this, &key); - m_instrument->restoreState( node.firstChildElement() ); - - emit instrumentChanged(); + if (reuseInstrument) + { + m_instrument->restoreState(node.firstChildElement()); + } + else + { + delete m_instrument; + m_instrument = NULL; + m_instrument = Instrument::instantiate( + node.toElement().attribute("name"), this, &key); + m_instrument->restoreState(node.firstChildElement()); + emit instrumentChanged(); + } } // compat code - if node-name doesn't match any known // one, we assume that it is an instrument-plugin // which we'll try to load - else if( AutomationPattern::classNodeName() != node.nodeName() && + else if(AutomationPattern::classNodeName() != node.nodeName() && ControllerConnection::classNodeName() != node.nodeName() && - !node.toElement().hasAttribute( "id" ) ) + !node.toElement().hasAttribute( "id" )) { delete m_instrument; m_instrument = NULL; m_instrument = Instrument::instantiate( node.nodeName(), this, nullptr, true); - if( m_instrument->nodeName() == node.nodeName() ) + if (m_instrument->nodeName() == node.nodeName()) { - m_instrument->restoreState( node.toElement() ); + m_instrument->restoreState(node.toElement()); } emit instrumentChanged(); } @@ -863,6 +873,19 @@ void InstrumentTrack::setPreviewMode( const bool value ) +QString InstrumentTrack::getSavedInstrumentName(const QDomElement &thisElement) const +{ + QDomElement elem = thisElement.firstChildElement("instrument"); + if (!elem.isNull()) + { + return elem.attribute("name"); + } + return ""; +} + + + + Instrument * InstrumentTrack::loadInstrument(const QString & _plugin_name, const Plugin::Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd) {