diff --git a/ChangeLog b/ChangeLog index 8c786086b..e88094449 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2008-10-04 Tobias Doerffel + * plugins/ladspa_effect/ladspa_effect.cpp: + * include/automatable_model.h: + * include/automation_pattern.h: + * src/core/automatable_model.cpp: + * src/core/ladspa_control.cpp: + * src/core/automation_pattern.cpp: + fixed lost automation relations when switching samplerate + * plugins/lb302/lb302.cpp: * plugins/lb302/lb302.h: * plugins/bass_booster/bass_booster.cpp: diff --git a/include/automatable_model.h b/include/automatable_model.h index 9281bbabf..cd1da11c7 100644 --- a/include/automatable_model.h +++ b/include/automatable_model.h @@ -259,6 +259,7 @@ private: signals: void initValueChanged( float _val ); + void destroyed( jo_id_t _id ); } ; diff --git a/include/automation_pattern.h b/include/automation_pattern.h index a24b12904..28ca99a41 100644 --- a/include/automation_pattern.h +++ b/include/automation_pattern.h @@ -49,30 +49,30 @@ public: automationPattern( const automationPattern & _pat_to_copy ); virtual ~automationPattern(); - void addObject( automatableModel * _obj ); + void addObject( automatableModel * _obj, bool _search_dup = true ); const automatableModel * firstObject( void ) const; virtual midiTime length( void ) const; midiTime putValue( const midiTime & _time, const float _value, - const bool _quant_pos = TRUE ); + const bool _quant_pos = true ); void removeValue( const midiTime & _time ); inline const timeMap & getTimeMap( void ) const { - return( m_timeMap ); + return m_timeMap; } inline timeMap & getTimeMap( void ) { - return( m_timeMap ); + return m_timeMap; } inline bool hasAutomation( void ) const { - return( m_hasAutomation ); + return m_hasAutomation; } float valueAt( const midiTime & _time ) const; @@ -85,12 +85,12 @@ public: static inline const QString classNodeName( void ) { - return( "automationpattern" ); + return "automationpattern"; } inline virtual QString nodeName( void ) const { - return( classNodeName() ); + return classNodeName(); } void processMidiTime( const midiTime & _time ); @@ -105,8 +105,9 @@ public: public slots: - void openInAutomationEditor( void ); void clear( void ); + void openInAutomationEditor( void ); + void objectDestroyed( jo_id_t ); private: @@ -147,7 +148,7 @@ protected: virtual void paintEvent( QPaintEvent * _pe ); virtual void resizeEvent( QResizeEvent * _re ) { - m_needsUpdate = TRUE; + m_needsUpdate = true; trackContentObjectView::resizeEvent( _re ); } virtual void dragEnterEvent( QDragEnterEvent * _dee ); @@ -162,5 +163,4 @@ private: } ; - #endif diff --git a/plugins/ladspa_effect/ladspa_effect.cpp b/plugins/ladspa_effect/ladspa_effect.cpp index f96d23c3b..453471c98 100644 --- a/plugins/ladspa_effect/ladspa_effect.cpp +++ b/plugins/ladspa_effect/ladspa_effect.cpp @@ -34,6 +34,7 @@ #include "ladspa_subplugin_features.h" #include "mixer.h" #include "effect_chain.h" +#include "automation_pattern.h" #undef SINGLE_SOURCE_COMPILE @@ -105,15 +106,23 @@ void ladspaEffect::changeSampleRate( void ) { multimediaProject mmp( multimediaProject::EffectSettings ); m_controls->saveState( mmp, mmp.content() ); + ladspaControls * controls = m_controls; m_controls = NULL; + m_pluginMutex.lock(); pluginDestruction(); pluginInstantiation(); m_pluginMutex.unlock(); - m_controls->restoreState( mmp.content().firstChild().toElement() ); + controls->effectModelChanged( m_controls ); delete controls; + + m_controls->restoreState( mmp.content().firstChild().toElement() ); + + // the IDs of re-created controls have been saved and now need to be + // resolved again + automationPattern::resolveAllIDs(); } diff --git a/src/core/automatable_model.cpp b/src/core/automatable_model.cpp index e8959c23c..f12290d9a 100644 --- a/src/core/automatable_model.cpp +++ b/src/core/automatable_model.cpp @@ -72,6 +72,8 @@ automatableModel::~automatableModel() { delete m_controllerConnection; } + + emit destroyed( id() ); } diff --git a/src/core/automation_pattern.cpp b/src/core/automation_pattern.cpp index 9ca92f9a1..302904838 100644 --- a/src/core/automation_pattern.cpp +++ b/src/core/automation_pattern.cpp @@ -1,5 +1,3 @@ -#ifndef SINGLE_SOURCE_COMPILE - /* * automation_pattern.cpp - implementation of class automationPattern which * holds dynamic values @@ -31,7 +29,6 @@ #include #include - #include "automation_pattern.h" #include "automation_track.h" #include "automation_editor.h" @@ -50,12 +47,11 @@ - automationPattern::automationPattern( automationTrack * _auto_track ) : trackContentObject( _auto_track ), m_autoTrack( _auto_track ), m_objects(), - m_hasAutomation( FALSE ) + m_hasAutomation( false ) { changeLength( midiTime( 1, 0 ) ); m_timeMap[0] = 0; @@ -92,18 +88,22 @@ automationPattern::~automationPattern() -void automationPattern::addObject( automatableModel * _obj ) +void automationPattern::addObject( automatableModel * _obj, bool _search_dup ) { bool addIt = true; - for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ++it ) + if( _search_dup ) { - if( *it == _obj ) { - // Already exists - // TODO: Maybe let the user know in some non-annoying way - addIt = false; - break; + for( objectVector::iterator it = m_objects.begin(); + it != m_objects.end(); ++it ) + { + if( *it == _obj ) + { + // Already exists + // TODO: Maybe let the user know in some non-annoying way + addIt = false; + break; + } } } @@ -114,8 +114,11 @@ void automationPattern::addObject( automatableModel * _obj ) if( m_objects.size() == 1 && !hasAutomation() ) { // then initialize default-value - putValue( 0, _obj->value(), FALSE ); + putValue( 0, _obj->value(), false ); } + connect( _obj, SIGNAL( destroyed( jo_id_t ) ), + this, SLOT( objectDestroyed( jo_id_t ) ), + Qt::DirectConnection ); } } @@ -127,11 +130,11 @@ const automatableModel * automationPattern::firstObject( void ) const automatableModel * m; if( !m_objects.isEmpty() && ( m = m_objects.first() ) != NULL ) { - return( m ); + return m; } static floatModel _fm( 0, 0, 1, 0.001 ); - return( &_fm ); + return &_fm; } @@ -148,8 +151,7 @@ midiTime automationPattern::length( void ) const { max_length = qMax( max_length, it.key() ); } - return( midiTime( qMax( midiTime( max_length ).getTact() + 1, 1 ), - 0 ) ); + return midiTime( qMax( midiTime( max_length ).getTact() + 1, 1 ), 0 ); } @@ -168,17 +170,22 @@ midiTime automationPattern::putValue( const midiTime & _time, if( new_time != 0 ) { - m_hasAutomation = TRUE; + m_hasAutomation = true; } else { - m_hasAutomation = FALSE; + m_hasAutomation = false; for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ++it ) + it != m_objects.end(); ) { if( *it ) { ( *it )->setValue( _value ); + ++it; + } + else + { + it = m_objects.erase( it ); } } } @@ -190,7 +197,7 @@ midiTime automationPattern::putValue( const midiTime & _time, emit dataChanged(); - return( new_time ); + return new_time; } @@ -204,13 +211,14 @@ void automationPattern::removeValue( const midiTime & _time ) if( m_timeMap.size() <= 1 ) { - m_hasAutomation = FALSE; + m_hasAutomation = false; for( objectVector::iterator it = m_objects.begin(); - it != m_objects.end(); ++it ) + it != m_objects.end(); ) { if( *it ) { ( *it )->setValue( m_timeMap[0] ); + ++it; } else { @@ -232,42 +240,16 @@ void automationPattern::removeValue( const midiTime & _time ) -void automationPattern::clear( void ) -{ - const float val = firstObject()->value(); - m_timeMap.clear(); - putValue( 0, val ); - - if( engine::getAutomationEditor() && - engine::getAutomationEditor()->currentPattern() == this ) - { - engine::getAutomationEditor()->update(); - } -} - - - - -void automationPattern::openInAutomationEditor( void ) -{ - engine::getAutomationEditor()->setCurrentPattern( this ); - engine::getAutomationEditor()->parentWidget()->show(); - engine::getAutomationEditor()->setFocus(); -} - - - - float automationPattern::valueAt( const midiTime & _time ) const { if( m_timeMap.isEmpty() ) { - return( 0 ); + return 0; } timeMap::const_iterator v = m_timeMap.lowerBound( _time ); // lowerBound returns next value with greater key, therefore we take // the previous element to get the current value - return( ( v != m_timeMap.begin() ) ? (v-1).value() : v.value() ); + return ( v != m_timeMap.begin() ) ? (v-1).value() : v.value(); } @@ -329,7 +311,7 @@ void automationPattern::loadSettings( const QDomElement & _this ) } m_hasAutomation = m_timeMap.size() > 1; - if( m_hasAutomation == FALSE ) + if( m_hasAutomation == false ) { for( objectVector::iterator it = m_objects.begin(); it != m_objects.end(); ++it ) @@ -351,13 +333,13 @@ const QString automationPattern::name( void ) const { if( !trackContentObject::name().isEmpty() ) { - return( trackContentObject::name() ); + return trackContentObject::name(); } if( !m_objects.isEmpty() && m_objects.first() != NULL ) { - return( m_objects.first()->fullDisplayName() ); + return m_objects.first()->fullDisplayName(); } - return( tr( "Drag a control while pressing " ) ); + return tr( "Drag a control while pressing " ); } @@ -386,7 +368,7 @@ void automationPattern::processMidiTime( const midiTime & _time ) trackContentObjectView * automationPattern::createView( trackView * _tv ) { - return( new automationPatternView( this, _tv ) ); + return new automationPatternView( this, _tv ); } @@ -418,14 +400,14 @@ bool automationPattern::isAutomated( const automatableModel * _m ) { if( *k == _m ) { - return( TRUE ); + return true; } } } } } } - return( FALSE ); + return false; } @@ -448,15 +430,15 @@ automationPattern * automationPattern::globalAutomationPattern( { if( *k == _m ) { - return( a ); + return a; } } } } automationPattern * a = new automationPattern( t ); - a->m_objects += _m; - return( a ); + a->addObject( _m, false ); + return a; } @@ -488,7 +470,7 @@ void automationPattern::resolveAllIDs( void ) getJournallingObject( *k ); if( o && dynamic_cast( o ) ) { - a->m_objects += dynamic_cast( o ); + a->addObject( dynamic_cast( o ), false ); } } a->m_idsToResolve.clear(); @@ -502,6 +484,43 @@ void automationPattern::resolveAllIDs( void ) +void automationPattern::clear( void ) +{ + const float val = firstObject()->value(); + m_timeMap.clear(); + putValue( 0, val ); + + if( engine::getAutomationEditor() && + engine::getAutomationEditor()->currentPattern() == this ) + { + engine::getAutomationEditor()->update(); + } +} + + + + +void automationPattern::openInAutomationEditor( void ) +{ + engine::getAutomationEditor()->setCurrentPattern( this ); + engine::getAutomationEditor()->parentWidget()->show(); + engine::getAutomationEditor()->setFocus(); +} + + + + +void automationPattern::objectDestroyed( jo_id_t _id ) +{ + // TODO: distict between temporary removal (e.g. LADSPA controls + // when switching samplerate) and real deletions because in the latter + // case we had to remove ourselves if we're the global automation + // pattern of the destroyed object + m_idsToResolve += _id; +} + + + automationPatternView::automationPatternView( automationPattern * _pattern, @@ -509,13 +528,13 @@ automationPatternView::automationPatternView( automationPattern * _pattern, trackContentObjectView( _pattern, _parent ), m_pat( _pattern ), m_paintPixmap(), - m_needsUpdate( TRUE ) + m_needsUpdate( true ) { connect( m_pat, SIGNAL( dataChanged() ), this, SLOT( update() ) ); setFixedHeight( parentWidget()->height() - 2 ); - setAutoResizeEnabled( FALSE ); + setAutoResizeEnabled( false ); toolTip::add( this, tr( "double-click to open this pattern in " "automation editor" ) ); @@ -534,7 +553,7 @@ automationPatternView::~automationPatternView() void automationPatternView::update( void ) { - m_needsUpdate = TRUE; + m_needsUpdate = true; if( fixedTCOs() ) { m_pat->changeLength( m_pat->length() ); @@ -644,16 +663,16 @@ void automationPatternView::mouseDoubleClickEvent( QMouseEvent * _me ) void automationPatternView::paintEvent( QPaintEvent * ) { - if( m_needsUpdate == FALSE ) + if( m_needsUpdate == false ) { QPainter p( this ); p.drawPixmap( 0, 0, m_paintPixmap ); return; } - m_needsUpdate = FALSE; + m_needsUpdate = false; - if( m_paintPixmap.isNull() == TRUE || m_paintPixmap.size() != size() ) + if( m_paintPixmap.isNull() == true || m_paintPixmap.size() != size() ) { m_paintPixmap = QPixmap( size() ); } @@ -798,9 +817,5 @@ void automationPatternView::dropEvent( QDropEvent * _de ) - - #include "moc_automation_pattern.cxx" - -#endif diff --git a/src/core/ladspa_control.cpp b/src/core/ladspa_control.cpp index 845b8043b..6e0267f22 100644 --- a/src/core/ladspa_control.cpp +++ b/src/core/ladspa_control.cpp @@ -187,6 +187,7 @@ void ladspaControl::saveSettings( QDomDocument & _doc, + void ladspaControl::loadSettings( const QDomElement & _this, const QString & _name ) {