From ee758431fe50dfe6d9be227dfe17812752e27fac Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 24 Aug 2020 10:31:29 -0300 Subject: [PATCH 1/6] Play automation pattern when midi controller connected --- include/AutomatableModel.h | 27 +++++++++++- include/AutomatableModelView.h | 2 + include/ControllerConnection.h | 10 ++++- include/Song.h | 2 + src/core/AutomatableModel.cpp | 70 ++++++++++++++++++++----------- src/core/ControllerConnection.cpp | 23 ++++++++-- src/core/Song.cpp | 22 +++++++++- src/gui/AutomatableModelView.cpp | 18 +++++++- 8 files changed, 142 insertions(+), 32 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index c332858b7b6..06dbef18991 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -28,12 +28,14 @@ #include #include + #include "JournallingObject.h" #include "Model.h" #include "MidiTime.h" #include "ValueBuffer.h" #include "MemoryManager.h" #include "ModelVisitor.h" +#include "ControllerConnection.h" // simple way to map a property of a view to a model #define mapPropertyFromModelPtr(type,getfunc,setfunc,modelname) \ @@ -148,7 +150,18 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject template inline T value( int frameOffset = 0 ) const { - if( hasLinkedModels() || m_controllerConnection != NULL ) + if (m_controllerConnection) + { + if (m_controllerConnection->isControllerMidi() && !m_controllerValue) + { + return castValue(m_value); + } + else + { + return castValue(controllerValue(frameOffset)); + } + } + else if (hasLinkedModels()) { return castValue( controllerValue( frameOffset ) ); } @@ -298,9 +311,19 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject s_periodCounter = 0; } + bool isControllerValue() + { + return m_controllerValue; + } + void setControllerValue(bool b) + { + m_controllerValue = b; + } + public slots: virtual void reset(); void unlinkControllerConnection(); + void setAndEmitControllerValue(); protected: @@ -395,6 +418,8 @@ public slots: // prevent several threads from attempting to write the same vb at the same time QMutex m_valueBufferMutex; + bool m_controllerValue; + signals: void initValueChanged( float val ); void destroyed( jo_id_t id ); diff --git a/include/AutomatableModelView.h b/include/AutomatableModelView.h index 1bcbd97d6fe..adb1f74991b 100644 --- a/include/AutomatableModelView.h +++ b/include/AutomatableModelView.h @@ -102,6 +102,8 @@ private slots: protected: AutomatableModelView* m_amv; + void disconnectStopSignalMidi(AutomatableModel * autmod); + } ; diff --git a/include/ControllerConnection.h b/include/ControllerConnection.h index e57cd4db2f5..81a3faf255a 100644 --- a/include/ControllerConnection.h +++ b/include/ControllerConnection.h @@ -33,6 +33,7 @@ #include #include +#include "AutomatableModel.h" #include "Controller.h" #include "JournallingObject.h" #include "ValueBuffer.h" @@ -47,7 +48,7 @@ class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObjec Q_OBJECT public: - ControllerConnection( Controller * _controller ); + ControllerConnection(Controller * _controller, AutomatableModel * contmod); ControllerConnection( int _controllerId ); virtual ~ControllerConnection(); @@ -98,6 +99,10 @@ class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObjec return classNodeName(); } + bool isControllerMidi() + { + return m_controllerMidi; + } public slots: void deleteConnection(); @@ -112,6 +117,9 @@ public slots: static ControllerConnectionVector s_connections; + bool m_controllerMidi; + AutomatableModel * m_controlledModel; + signals: // The value changed while the mixer isn't running (i.e: MIDI CC) void valueChanged(); diff --git a/include/Song.h b/include/Song.h index 47367828194..f28847e5e8f 100644 --- a/include/Song.h +++ b/include/Song.h @@ -464,6 +464,8 @@ private slots: MidiTime m_exportSongEnd; MidiTime m_exportEffectiveLength; + AutomatedValueMap m_oldAutomatedValues; + friend class LmmsCore; friend class SongEditor; friend class mainWindow; diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 8328e5cb9ea..4c215d79f1a 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -53,7 +53,8 @@ AutomatableModel::AutomatableModel( m_controllerConnection( NULL ), m_valueBuffer( static_cast( Engine::mixer()->framesPerPeriod() ) ), m_lastUpdatedPeriod( -1 ), - m_hasSampleExactData( false ) + m_hasSampleExactData(false), + m_controllerValue(true) { m_value = fittedValue( val ); @@ -214,7 +215,7 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString& } if( thisConnection.isElement() ) { - setControllerConnection( new ControllerConnection( (Controller*)NULL ) ); + setControllerConnection(new ControllerConnection((Controller*)NULL, this)); m_controllerConnection->loadSettings( thisConnection.toElement() ); //m_controllerConnection->setTargetName( displayName() ); } @@ -371,6 +372,14 @@ void AutomatableModel::roundAt( T& value, const T& where ) const void AutomatableModel::setAutomatedValue( const float value ) { + bool emitDataChanged = false; + + if (m_controllerConnection && m_controllerValue && m_controllerConnection->isControllerMidi()) + { + m_controllerValue = false; + emitDataChanged = true; + } + m_oldValue = m_value; ++m_setValueDepth; const float oldValue = m_value; @@ -382,18 +391,20 @@ void AutomatableModel::setAutomatedValue( const float value ) if( oldValue != m_value ) { // notify linked models - for( AutoModelVector::Iterator it = m_linkedModels.begin(); - it != m_linkedModels.end(); ++it ) + for (AutoModelVector::Iterator it = m_linkedModels.begin(); + it != m_linkedModels.end(); ++it) { - if( (*it)->m_setValueDepth < 1 && - (*it)->fittedValue( m_value ) != (*it)->m_value ) + if (!((*it)->controllerConnection()) && (*it)->m_setValueDepth < 1 && + (*it)->fittedValue(m_value) != (*it)->m_value) { - (*it)->setAutomatedValue( value ); + (*it)->setAutomatedValue(value); } } m_valueChanged = true; - emit dataChanged(); + emitDataChanged = true; } + + if (emitDataChanged) {emit dataChanged();} --m_setValueDepth; } @@ -584,7 +595,7 @@ float AutomatableModel::controllerValue( int frameOffset ) const } AutomatableModel* lm = m_linkedModels.first(); - if( lm->controllerConnection() ) + if (lm->controllerConnection() && lm->isControllerValue()) { return fittedValue( lm->controllerValue( frameOffset ) ); } @@ -607,7 +618,7 @@ ValueBuffer * AutomatableModel::valueBuffer() float val = m_value; // make sure our m_value doesn't change midway ValueBuffer * vb; - if( m_controllerConnection && m_controllerConnection->getController()->isSampleExact() ) + if (m_controllerConnection && m_controllerValue && m_controllerConnection->getController()->isSampleExact()) { vb = m_controllerConnection->valueBuffer(); if( vb ) @@ -638,23 +649,28 @@ ValueBuffer * AutomatableModel::valueBuffer() return &m_valueBuffer; } } - AutomatableModel* lm = NULL; - if( hasLinkedModels() ) - { - lm = m_linkedModels.first(); - } - if( lm && lm->controllerConnection() && lm->controllerConnection()->getController()->isSampleExact() ) + + if (!m_controllerConnection) { - vb = lm->valueBuffer(); - float * values = vb->values(); - float * nvalues = m_valueBuffer.values(); - for( int i = 0; i < vb->length(); i++ ) + AutomatableModel* lm = NULL; + if (hasLinkedModels()) { - nvalues[i] = fittedValue( values[i] ); + lm = m_linkedModels.first(); + } + if (lm && lm->controllerConnection() && lm->isControllerValue() && + lm->controllerConnection()->getController()->isSampleExact()) + { + vb = lm->valueBuffer(); + float * values = vb->values(); + float * nvalues = m_valueBuffer.values(); + for (int i = 0; i < vb->length(); i++) + { + nvalues[i] = fittedValue(values[i]); + } + m_lastUpdatedPeriod = s_periodCounter; + m_hasSampleExactData = true; + return &m_valueBuffer; } - m_lastUpdatedPeriod = s_periodCounter; - m_hasSampleExactData = true; - return &m_valueBuffer; } if( m_oldValue != val ) @@ -766,6 +782,12 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time ) } } +void AutomatableModel::setAndEmitControllerValue() +{ + m_controllerValue = true; + emit dataChanged(); +} + float FloatModel::getRoundedValue() const { return qRound( value() / step() ) * step(); diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index e08f15b6348..f4597fea5e3 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -36,10 +36,11 @@ ControllerConnectionVector ControllerConnection::s_connections; -ControllerConnection::ControllerConnection( Controller * _controller ) : +ControllerConnection::ControllerConnection(Controller * _controller, AutomatableModel * contmod) : m_controller( NULL ), m_controllerId( -1 ), - m_ownsController( false ) + m_ownsController(false), + m_controlledModel(contmod) { if( _controller != NULL ) { @@ -120,8 +121,22 @@ void ControllerConnection::setController( Controller * _controller ) this, SIGNAL( valueChanged() ), Qt::DirectConnection ); } - m_ownsController = - ( _controller->type() == Controller::MidiController ); + if (_controller->type() == Controller::MidiController) + { + + connect(Engine::getSong(), SIGNAL(stopped()), + m_controlledModel, SLOT(setAndEmitControllerValue()), + Qt::UniqueConnection); + + m_ownsController = true; + m_controllerMidi = true; + } + else + { + m_ownsController = false; + m_controllerMidi = false; + } + m_controlledModel->setControllerValue(true); // If we don't own the controller, allow deletion of controller // to delete the connection diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 5f63e6ee859..0f7c1675778 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -90,7 +90,8 @@ Song::Song() : m_elapsedTicks( 0 ), m_elapsedBars( 0 ), m_loopRenderCount(1), - m_loopRenderRemaining(1) + m_loopRenderRemaining(1), + m_oldAutomatedValues() { for(int i = 0; i < Mode_Count; ++i) m_elapsedMilliSeconds[i] = 0; connect( &m_tempoModel, SIGNAL( dataChanged() ), @@ -467,6 +468,21 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp } } + if (!m_oldAutomatedValues.isEmpty()) + { + for (auto it = m_oldAutomatedValues.begin(); it != m_oldAutomatedValues.end(); it++) + { + AutomatableModel * am = it.key(); + if (am->controllerConnection() && + am->controllerConnection()->isControllerMidi() && + !values.contains(am)) + { + am->setAndEmitControllerValue(); + } + } + } + m_oldAutomatedValues = values; + // Apply values for (auto it = values.begin(); it != values.end(); it++) { @@ -474,6 +490,10 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp { it.key()->setAutomatedValue(it.value()); } + else if (!it.key()->isControllerValue()) + { + it.key()->setAndEmitControllerValue(); + } } } diff --git a/src/gui/AutomatableModelView.cpp b/src/gui/AutomatableModelView.cpp index 039c75c9953..59349f915b1 100644 --- a/src/gui/AutomatableModelView.cpp +++ b/src/gui/AutomatableModelView.cpp @@ -34,6 +34,7 @@ #include "embed.h" #include "GuiApplication.h" #include "MainWindow.h" +#include "Song.h" #include "StringPairDrag.h" #include "AutomationEditor.h" @@ -185,12 +186,17 @@ void AutomatableModelViewSlots::execConnectionDialog() // Update if( m->controllerConnection() ) { + if (m->controllerConnection()->isControllerMidi() && + !(d.chosenController()->type() == Controller::MidiController)) + { + disconnectStopSignalMidi(m); + } m->controllerConnection()->setController( d.chosenController() ); } // New else { - ControllerConnection* cc = new ControllerConnection( d.chosenController() ); + ControllerConnection* cc = new ControllerConnection(d.chosenController(), m); m->setControllerConnection( cc ); //cc->setTargetName( m->displayName() ); } @@ -212,8 +218,13 @@ void AutomatableModelViewSlots::removeConnection() if( m->controllerConnection() ) { + if (m->controllerConnection()->isControllerMidi()) + { + disconnectStopSignalMidi(m); + } delete m->controllerConnection(); m->setControllerConnection( NULL ); + emit m->dataChanged(); } } @@ -255,6 +266,11 @@ void AutomatableModelViewSlots::pasteFromClipboard() } } +void AutomatableModelViewSlots::disconnectStopSignalMidi(AutomatableModel * autmod) +{ + disconnect(Engine::getSong(), SIGNAL(stopped()), + autmod, SLOT(setAndEmitControllerValue())); +} /// Attempt to parse a float from the clipboard static float floatFromClipboard(bool* ok) From e65e12ac80d41de1fdafcc217c2b9561f942ff7c Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 24 Aug 2020 10:59:29 -0300 Subject: [PATCH 2/6] empty line removed --- include/AutomatableModel.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index 06dbef18991..d9dfb86d458 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -28,7 +28,6 @@ #include #include - #include "JournallingObject.h" #include "Model.h" #include "MidiTime.h" From 8309dd3005cfc01678f298d5088c9eacbcf3993f Mon Sep 17 00:00:00 2001 From: Andres Date: Thu, 14 Jan 2021 12:15:02 -0300 Subject: [PATCH 3/6] Improved for clarity --- include/AutomatableModel.h | 14 +++++------- src/core/AutomatableModel.cpp | 37 ++++++++++++++++--------------- src/core/ControllerConnection.cpp | 4 ++-- src/core/Song.cpp | 6 ++--- src/gui/AutomatableModelView.cpp | 2 +- 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index d9dfb86d458..db6216fc4bb 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -151,7 +151,7 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject { if (m_controllerConnection) { - if (m_controllerConnection->isControllerMidi() && !m_controllerValue) + if (m_controllerConnection->isControllerMidi() && !m_useControllerValue) { return castValue(m_value); } @@ -310,19 +310,15 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject s_periodCounter = 0; } - bool isControllerValue() + bool useControllerValue() { - return m_controllerValue; - } - void setControllerValue(bool b) - { - m_controllerValue = b; + return m_useControllerValue; } public slots: virtual void reset(); void unlinkControllerConnection(); - void setAndEmitControllerValue(); + void setUseControllerValue(bool b = true); protected: @@ -417,7 +413,7 @@ public slots: // prevent several threads from attempting to write the same vb at the same time QMutex m_valueBufferMutex; - bool m_controllerValue; + bool m_useControllerValue; signals: void initValueChanged( float val ); diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index 4c215d79f1a..d72c9539800 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -54,7 +54,7 @@ AutomatableModel::AutomatableModel( m_valueBuffer( static_cast( Engine::mixer()->framesPerPeriod() ) ), m_lastUpdatedPeriod( -1 ), m_hasSampleExactData(false), - m_controllerValue(true) + m_useControllerValue(true) { m_value = fittedValue( val ); @@ -372,14 +372,8 @@ void AutomatableModel::roundAt( T& value, const T& where ) const void AutomatableModel::setAutomatedValue( const float value ) { - bool emitDataChanged = false; - - if (m_controllerConnection && m_controllerValue && m_controllerConnection->isControllerMidi()) - { - m_controllerValue = false; - emitDataChanged = true; - } - + setUseControllerValue(false); + m_oldValue = m_value; ++m_setValueDepth; const float oldValue = m_value; @@ -401,10 +395,8 @@ void AutomatableModel::setAutomatedValue( const float value ) } } m_valueChanged = true; - emitDataChanged = true; + emit dataChanged(); } - - if (emitDataChanged) {emit dataChanged();} --m_setValueDepth; } @@ -595,7 +587,7 @@ float AutomatableModel::controllerValue( int frameOffset ) const } AutomatableModel* lm = m_linkedModels.first(); - if (lm->controllerConnection() && lm->isControllerValue()) + if (lm->controllerConnection() && lm->useControllerValue()) { return fittedValue( lm->controllerValue( frameOffset ) ); } @@ -618,7 +610,7 @@ ValueBuffer * AutomatableModel::valueBuffer() float val = m_value; // make sure our m_value doesn't change midway ValueBuffer * vb; - if (m_controllerConnection && m_controllerValue && m_controllerConnection->getController()->isSampleExact()) + if (m_controllerConnection && m_useControllerValue && m_controllerConnection->getController()->isSampleExact()) { vb = m_controllerConnection->valueBuffer(); if( vb ) @@ -657,7 +649,7 @@ ValueBuffer * AutomatableModel::valueBuffer() { lm = m_linkedModels.first(); } - if (lm && lm->controllerConnection() && lm->isControllerValue() && + if (lm && lm->controllerConnection() && lm->useControllerValue() && lm->controllerConnection()->getController()->isSampleExact()) { vb = lm->valueBuffer(); @@ -782,10 +774,19 @@ float AutomatableModel::globalAutomationValueAt( const MidiTime& time ) } } -void AutomatableModel::setAndEmitControllerValue() +void AutomatableModel::setUseControllerValue(bool b) { - m_controllerValue = true; - emit dataChanged(); + if (b) + { + m_useControllerValue = true; + emit dataChanged(); + } + else if (m_controllerConnection && m_useControllerValue && m_controllerConnection->isControllerMidi()) + { + m_useControllerValue = false; + emit dataChanged(); + } + } float FloatModel::getRoundedValue() const diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index f4597fea5e3..bec05707983 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -125,7 +125,7 @@ void ControllerConnection::setController( Controller * _controller ) { connect(Engine::getSong(), SIGNAL(stopped()), - m_controlledModel, SLOT(setAndEmitControllerValue()), + m_controlledModel, SLOT(setUseControllerValue()), Qt::UniqueConnection); m_ownsController = true; @@ -136,7 +136,7 @@ void ControllerConnection::setController( Controller * _controller ) m_ownsController = false; m_controllerMidi = false; } - m_controlledModel->setControllerValue(true); + m_controlledModel->setUseControllerValue(true); // If we don't own the controller, allow deletion of controller // to delete the connection diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 0f7c1675778..58ce6b0062e 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -477,7 +477,7 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp am->controllerConnection()->isControllerMidi() && !values.contains(am)) { - am->setAndEmitControllerValue(); + am->setUseControllerValue(true); } } } @@ -490,9 +490,9 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp { it.key()->setAutomatedValue(it.value()); } - else if (!it.key()->isControllerValue()) + else if (!it.key()->useControllerValue()) { - it.key()->setAndEmitControllerValue(); + it.key()->setUseControllerValue(true); } } } diff --git a/src/gui/AutomatableModelView.cpp b/src/gui/AutomatableModelView.cpp index 59349f915b1..f0d7dc9d5ef 100644 --- a/src/gui/AutomatableModelView.cpp +++ b/src/gui/AutomatableModelView.cpp @@ -269,7 +269,7 @@ void AutomatableModelViewSlots::pasteFromClipboard() void AutomatableModelViewSlots::disconnectStopSignalMidi(AutomatableModel * autmod) { disconnect(Engine::getSong(), SIGNAL(stopped()), - autmod, SLOT(setAndEmitControllerValue())); + autmod, SLOT(setUseControllerValue())); } /// Attempt to parse a float from the clipboard From d0ba16d8cd837910b43074bcb26208296d293f8c Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 18 Jan 2021 12:46:59 -0300 Subject: [PATCH 4/6] removed midi specific controller logic --- include/AutomatableModel.h | 2 +- include/AutomatableModelView.h | 2 -- include/ControllerConnection.h | 6 ------ src/core/AutomatableModel.cpp | 5 ++--- src/core/ControllerConnection.cpp | 12 ++---------- src/core/Song.cpp | 4 +--- src/gui/AutomatableModelView.cpp | 18 +++--------------- 7 files changed, 9 insertions(+), 40 deletions(-) diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h index db6216fc4bb..d36dcfe8767 100644 --- a/include/AutomatableModel.h +++ b/include/AutomatableModel.h @@ -151,7 +151,7 @@ class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject { if (m_controllerConnection) { - if (m_controllerConnection->isControllerMidi() && !m_useControllerValue) + if (!m_useControllerValue) { return castValue(m_value); } diff --git a/include/AutomatableModelView.h b/include/AutomatableModelView.h index adb1f74991b..1bcbd97d6fe 100644 --- a/include/AutomatableModelView.h +++ b/include/AutomatableModelView.h @@ -102,8 +102,6 @@ private slots: protected: AutomatableModelView* m_amv; - void disconnectStopSignalMidi(AutomatableModel * autmod); - } ; diff --git a/include/ControllerConnection.h b/include/ControllerConnection.h index 81a3faf255a..322f22419d4 100644 --- a/include/ControllerConnection.h +++ b/include/ControllerConnection.h @@ -99,11 +99,6 @@ class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObjec return classNodeName(); } - bool isControllerMidi() - { - return m_controllerMidi; - } - public slots: void deleteConnection(); @@ -117,7 +112,6 @@ public slots: static ControllerConnectionVector s_connections; - bool m_controllerMidi; AutomatableModel * m_controlledModel; signals: diff --git a/src/core/AutomatableModel.cpp b/src/core/AutomatableModel.cpp index d72c9539800..c76fd353afe 100644 --- a/src/core/AutomatableModel.cpp +++ b/src/core/AutomatableModel.cpp @@ -373,7 +373,7 @@ void AutomatableModel::roundAt( T& value, const T& where ) const void AutomatableModel::setAutomatedValue( const float value ) { setUseControllerValue(false); - + m_oldValue = m_value; ++m_setValueDepth; const float oldValue = m_value; @@ -781,12 +781,11 @@ void AutomatableModel::setUseControllerValue(bool b) m_useControllerValue = true; emit dataChanged(); } - else if (m_controllerConnection && m_useControllerValue && m_controllerConnection->isControllerMidi()) + else if (m_controllerConnection && m_useControllerValue) { m_useControllerValue = false; emit dataChanged(); } - } float FloatModel::getRoundedValue() const diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index bec05707983..d49659ebb3c 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -121,21 +121,13 @@ void ControllerConnection::setController( Controller * _controller ) this, SIGNAL( valueChanged() ), Qt::DirectConnection ); } - if (_controller->type() == Controller::MidiController) - { + m_ownsController = + (_controller->type() == Controller::MidiController); connect(Engine::getSong(), SIGNAL(stopped()), m_controlledModel, SLOT(setUseControllerValue()), Qt::UniqueConnection); - m_ownsController = true; - m_controllerMidi = true; - } - else - { - m_ownsController = false; - m_controllerMidi = false; - } m_controlledModel->setUseControllerValue(true); // If we don't own the controller, allow deletion of controller diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 58ce6b0062e..5fd54a3f1c4 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -473,9 +473,7 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp for (auto it = m_oldAutomatedValues.begin(); it != m_oldAutomatedValues.end(); it++) { AutomatableModel * am = it.key(); - if (am->controllerConnection() && - am->controllerConnection()->isControllerMidi() && - !values.contains(am)) + if (am->controllerConnection() && !values.contains(am)) { am->setUseControllerValue(true); } diff --git a/src/gui/AutomatableModelView.cpp b/src/gui/AutomatableModelView.cpp index f0d7dc9d5ef..ca16c6d8c8a 100644 --- a/src/gui/AutomatableModelView.cpp +++ b/src/gui/AutomatableModelView.cpp @@ -186,11 +186,6 @@ void AutomatableModelViewSlots::execConnectionDialog() // Update if( m->controllerConnection() ) { - if (m->controllerConnection()->isControllerMidi() && - !(d.chosenController()->type() == Controller::MidiController)) - { - disconnectStopSignalMidi(m); - } m->controllerConnection()->setController( d.chosenController() ); } // New @@ -218,10 +213,9 @@ void AutomatableModelViewSlots::removeConnection() if( m->controllerConnection() ) { - if (m->controllerConnection()->isControllerMidi()) - { - disconnectStopSignalMidi(m); - } + disconnect(Engine::getSong(), SIGNAL(stopped()), + m, SLOT(setUseControllerValue())); + delete m->controllerConnection(); m->setControllerConnection( NULL ); emit m->dataChanged(); @@ -266,12 +260,6 @@ void AutomatableModelViewSlots::pasteFromClipboard() } } -void AutomatableModelViewSlots::disconnectStopSignalMidi(AutomatableModel * autmod) -{ - disconnect(Engine::getSong(), SIGNAL(stopped()), - autmod, SLOT(setUseControllerValue())); -} - /// Attempt to parse a float from the clipboard static float floatFromClipboard(bool* ok) { From 55e8fe2c3b7a3fab55b8d4e783ae95d240921ec5 Mon Sep 17 00:00:00 2001 From: Andres Date: Mon, 18 Jan 2021 13:02:07 -0300 Subject: [PATCH 5/6] formatting changes --- src/core/ControllerConnection.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/ControllerConnection.cpp b/src/core/ControllerConnection.cpp index d49659ebb3c..b8fe4b30244 100644 --- a/src/core/ControllerConnection.cpp +++ b/src/core/ControllerConnection.cpp @@ -124,9 +124,9 @@ void ControllerConnection::setController( Controller * _controller ) m_ownsController = (_controller->type() == Controller::MidiController); - connect(Engine::getSong(), SIGNAL(stopped()), - m_controlledModel, SLOT(setUseControllerValue()), - Qt::UniqueConnection); + connect(Engine::getSong(), SIGNAL(stopped()), + m_controlledModel, SLOT(setUseControllerValue()), + Qt::UniqueConnection); m_controlledModel->setUseControllerValue(true); From 406575f780048978350b33febb3a57edd499e600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 20 Jan 2021 16:50:45 -0300 Subject: [PATCH 6/6] comments added Co-authored-by: IanCaio --- src/core/Song.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 5fd54a3f1c4..9359f15571b 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -468,6 +468,8 @@ void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fp } } + // Checks if an automated model stopped being automated by automation patterns + // so we can move the control back to any connected controller again if (!m_oldAutomatedValues.isEmpty()) { for (auto it = m_oldAutomatedValues.begin(); it != m_oldAutomatedValues.end(); it++)