From 8fe009114d9cbffb498f4f68347edd95cfc4270d Mon Sep 17 00:00:00 2001 From: grindhold Date: Thu, 30 Oct 2014 23:43:43 +0100 Subject: [PATCH] implemented solo-buttons for FxMixer - resolving #1211 --- include/FxMixer.h | 9 ++++++ include/FxMixerView.h | 3 ++ src/core/FxMixer.cpp | 63 +++++++++++++++++++++++++++++++++++++++++ src/gui/FxMixerView.cpp | 24 +++++++++++++++- 4 files changed, 98 insertions(+), 1 deletion(-) diff --git a/include/FxMixer.h b/include/FxMixer.h index a4c3d2f0d..c387e4a62 100644 --- a/include/FxMixer.h +++ b/include/FxMixer.h @@ -51,7 +51,9 @@ class FxChannel : public ThreadableJob float m_peakLeft; float m_peakRight; sampleFrame * m_buffer; + bool m_muteBeforeSolo; BoolModel m_muteModel; + BoolModel m_soloModel; FloatModel m_volumeModel; QString m_name; QMutex m_lock; @@ -65,6 +67,7 @@ class FxChannel : public ThreadableJob FxRouteVector m_receives; virtual bool requiresProcessing() const { return true; } + void unmuteForSolo(); private: virtual void doProcessing( sampleFrame * _working_buffer ); @@ -174,6 +177,10 @@ public: // rename channels when moving etc. if they still have their original name void validateChannelName( int index, int oldIndex ); + void toggledSolo(); + void activateSolo(); + void deactivateSolo(); + inline fx_ch_t numChannels() const { return m_fxChannels.size(); @@ -191,6 +198,8 @@ private: void addChannelLeaf( FxChannel * ch, sampleFrame * buf ); + int m_lastSoloed; + friend class MixerWorkerThread; friend class FxMixerView; diff --git a/include/FxMixerView.h b/include/FxMixerView.h index aac3ad402..880f38d01 100644 --- a/include/FxMixerView.h +++ b/include/FxMixerView.h @@ -55,6 +55,7 @@ public: FxLine * m_fxLine; pixmapButton * m_muteBtn; + pixmapButton * m_soloBtn; fader * m_fader; EffectRackView * m_rackView; }; @@ -78,6 +79,7 @@ public: return m_fxChannelViews[index]; } + void setCurrentFxLine( FxLine * _line ); void setCurrentFxLine( int _line ); @@ -101,6 +103,7 @@ public: private slots: void updateFaders(); void addNewChannel(); + void toggledSolo(); private: diff --git a/src/core/FxMixer.cpp b/src/core/FxMixer.cpp index e41162ff1..69b101107 100644 --- a/src/core/FxMixer.cpp +++ b/src/core/FxMixer.cpp @@ -65,6 +65,7 @@ FxChannel::FxChannel( int idx, Model * _parent ) : m_peakRight( 0.0f ), m_buffer( new sampleFrame[engine::mixer()->framesPerPeriod()] ), m_muteModel( false, _parent ), + m_soloModel( false, _parent ), m_volumeModel( 1.0, 0.0, 2.0, 0.001, _parent ), m_name(), m_lock(), @@ -85,6 +86,13 @@ FxChannel::~FxChannel() +void FxChannel::unmuteForSolo() +{ + //TODO: Recursively activate every channel, this channel sends to + m_muteModel.setValue(false); +} + + void FxChannel::doProcessing( sampleFrame * _buf ) { @@ -175,6 +183,7 @@ FxMixer::FxMixer() : { // create master channel createChannel(); + m_lastSoloed = -1; } @@ -205,6 +214,57 @@ int FxMixer::createChannel() return index; } +void FxMixer::activateSolo() +{ + for (int i = 0; i < m_fxChannels.size(); ++i) + { + m_fxChannels[i]->m_muteBeforeSolo = m_fxChannels[i]->m_muteModel.value(); + m_fxChannels[i]->m_muteModel.setValue(true); + } +} + +void FxMixer::deactivateSolo() +{ + for (int i = 0; i < m_fxChannels.size(); ++i) + { + m_fxChannels[i]->m_muteModel.setValue(m_fxChannels[i]->m_muteBeforeSolo); + } +} + +void FxMixer::toggledSolo() +{ + int soloedChan = -1; + bool resetSolo = m_lastSoloed != -1; + //untoggle if lastsoloed is entered + if (resetSolo) + { + m_fxChannels[m_lastSoloed]->m_soloModel.setValue(false); + } + //determine the soloed channel + for (int i = 0; i < m_fxChannels.size(); ++i) + { + if (m_fxChannels[i]->m_soloModel.value() == true) + soloedChan = i; + } + // if no channel is soloed, unmute everything, else mute everything + if (soloedChan != -1) + { + if (resetSolo) + { + this->deactivateSolo(); + this->activateSolo(); + } else { + this->activateSolo(); + } + // unmute the soloed chan and every channel it sends to + m_fxChannels[soloedChan]->unmuteForSolo(); + } else { + this->deactivateSolo(); + } + m_lastSoloed = soloedChan; +} + + void FxMixer::deleteChannel( int index ) { @@ -568,6 +628,7 @@ void FxMixer::clearChannel(fx_ch_t index) ch->m_fxChain.clear(); ch->m_volumeModel.setValue( 1.0f ); ch->m_muteModel.setValue( false ); + ch->m_soloModel.setValue( false ); ch->m_name = ( index == 0 ) ? tr( "Master" ) : tr( "FX %1" ).arg( index ); ch->m_volumeModel.setDisplayName( ch->m_name ); @@ -604,6 +665,7 @@ void FxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this ) ch->m_fxChain.saveState( _doc, fxch ); ch->m_volumeModel.saveSettings( _doc, fxch, "volume" ); ch->m_muteModel.saveSettings( _doc, fxch, "muted" ); + ch->m_soloModel.saveSettings( _doc, fxch, "soloed" ); fxch.setAttribute( "num", i ); fxch.setAttribute( "name", ch->m_name ); @@ -650,6 +712,7 @@ void FxMixer::loadSettings( const QDomElement & _this ) m_fxChannels[num]->m_volumeModel.loadSettings( fxch, "volume" ); m_fxChannels[num]->m_muteModel.loadSettings( fxch, "muted" ); + m_fxChannels[num]->m_soloModel.loadSettings( fxch, "soloed" ); m_fxChannels[num]->m_name = fxch.attribute( "name" ); m_fxChannels[num]->m_fxChain.restoreState( fxch.firstChildElement( diff --git a/src/gui/FxMixerView.cpp b/src/gui/FxMixerView.cpp index 7f34efaa3..90bb700e0 100644 --- a/src/gui/FxMixerView.cpp +++ b/src/gui/FxMixerView.cpp @@ -192,6 +192,7 @@ void FxMixerView::refreshDisplay() chLayout->removeWidget(m_fxChannelViews[i]->m_fxLine); delete m_fxChannelViews[i]->m_fader; delete m_fxChannelViews[i]->m_muteBtn; + delete m_fxChannelViews[i]->m_soloBtn; delete m_fxChannelViews[i]->m_fxLine; delete m_fxChannelViews[i]; m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView ); @@ -276,8 +277,20 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, m_muteBtn->setInactiveGraphic( embed::getIconPixmap( "led_green" ) ); m_muteBtn->setCheckable( true ); - m_muteBtn->move( 9, m_fader->y()-16); + m_muteBtn->move( 9, m_fader->y()-11); toolTip::add( m_muteBtn, tr( "Mute this FX channel" ) ); + + m_soloBtn = new pixmapButton( m_fxLine, tr( "Solo" ) ); + m_soloBtn->setModel( &m->effectChannel(_chIndex)->m_soloModel ); + m_soloBtn->setActiveGraphic( + embed::getIconPixmap( "led_red" ) ); + m_soloBtn->setInactiveGraphic( + embed::getIconPixmap( "led_off" ) ); + m_soloBtn->setCheckable( true ); + m_soloBtn->move( 9, m_fader->y()-21); + connect(&m->effectChannel(_chIndex)->m_soloModel, SIGNAL( dataChanged() ), + _mv, SLOT ( toggledSolo() ) ); + toolTip::add( m_soloBtn, tr( "Solo FX channel" ) ); // Create EffectRack for the channel m_rackView = new EffectRackView( &m->effectChannel(_chIndex)->m_fxChain, _mv->m_racksWidget ); @@ -285,6 +298,13 @@ FxMixerView::FxChannelView::FxChannelView(QWidget * _parent, FxMixerView * _mv, } +void FxMixerView::toggledSolo() +{ + engine::fxMixer()->toggledSolo(); +} + + + void FxMixerView::setCurrentFxLine( FxLine * _line ) { // select @@ -341,6 +361,7 @@ void FxMixerView::deleteChannel(int index) chLayout->removeWidget(m_fxChannelViews[index]->m_fxLine); delete m_fxChannelViews[index]->m_fader; delete m_fxChannelViews[index]->m_muteBtn; + delete m_fxChannelViews[index]->m_soloBtn; delete m_fxChannelViews[index]->m_fxLine; delete m_fxChannelViews[index]; m_channelAreaWidget->adjustSize(); @@ -389,6 +410,7 @@ void FxMixerView::moveChannelLeft(int index) chLayout->removeWidget(m_fxChannelViews[i]->m_fxLine); delete m_fxChannelViews[i]->m_fader; delete m_fxChannelViews[i]->m_muteBtn; + delete m_fxChannelViews[i]->m_soloBtn; delete m_fxChannelViews[i]->m_fxLine; delete m_fxChannelViews[i]; m_racksLayout->removeWidget( m_fxChannelViews[i]->m_rackView );