diff options
Diffstat (limited to 'src')
47 files changed, 202 insertions, 295 deletions
diff --git a/src/control/control.cpp b/src/control/control.cpp index 2a29d83f90..f78f6b85a0 100644 --- a/src/control/control.cpp +++ b/src/control/control.cpp @@ -256,11 +256,3 @@ double ControlDoublePrivate::getMidiParameter() const { } return pBehavior->valueToMidiParameter(get()); } - -bool ControlDoublePrivate::connectValueChangeRequest(const QObject* receiver, - std::function<void(double)> method, Qt::ConnectionType type) { - // confirmation is only required if connect was successful - m_confirmRequired = connect(this, &ControlDoublePrivate::valueChangeRequest, - receiver, method, type); - return m_confirmRequired; -} diff --git a/src/control/control.h b/src/control/control.h index 596ea0a4f6..f0d87ec6eb 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -115,8 +115,14 @@ class ControlDoublePrivate : public QObject { // confirmed by setAndConfirm() or not. Note: Once connected, the CO value // itself is ONLY set by setAndConfirm() typically called in the connected // slot. - bool connectValueChangeRequest(const QObject* receiver, - std::function<void(double)> method, Qt::ConnectionType type); + template <typename Receiver, typename Slot> + bool connectValueChangeRequest(Receiver receiver, + Slot func, Qt::ConnectionType type) { + // confirmation is only required if connect was successful + m_confirmRequired = connect(this, &ControlDoublePrivate::valueChangeRequest, + receiver, func, type); + return m_confirmRequired; + } signals: // Emitted when the ControlDoublePrivate value changes. pSender is a diff --git a/src/control/controlindicator.cpp b/src/control/controlindicator.cpp index c3935f6403..fc18b845e2 100644 --- a/src/control/controlindicator.cpp +++ b/src/control/controlindicator.cpp @@ -9,7 +9,7 @@ ControlIndicator::ControlIndicator(ConfigKey key) // Tick time in audio buffer resolution m_pCOTGuiTickTime = new ControlProxy("[Master]", "guiTickTime", this); m_pCOTGuiTick50ms = new ControlProxy("[Master]", "guiTick50ms", this); - m_pCOTGuiTick50ms->connectValueChanged(SLOT(slotGuiTick50ms(double))); + m_pCOTGuiTick50ms->connectValueChanged(this, &ControlIndicator::slotGuiTick50ms); connect(this, SIGNAL(blinkValueChanged()), this, SLOT(slotBlinkValueChanged())); } diff --git a/src/control/controlobject.cpp b/src/control/controlobject.cpp index 75a6792671..57414d8881 100644 --- a/src/control/controlobject.cpp +++ b/src/control/controlobject.cpp @@ -117,18 +117,8 @@ void ControlObject::set(const ConfigKey& key, const double& value) { } } -bool ControlObject::connectValueChangeRequest(const QObject* receiver, - std::function<void(double)> method, - Qt::ConnectionType type) { - bool ret = false; - if (m_pControl) { - ret = m_pControl->connectValueChangeRequest(receiver, method, type); - } - return ret; -} - void ControlObject::setReadOnly() { - connectValueChangeRequest(this, [=](double value){readOnlyHandler(value);}, + connectValueChangeRequest(this, &ControlObject::readOnlyHandler, Qt::DirectConnection); } diff --git a/src/control/controlobject.h b/src/control/controlobject.h index 2902f82cef..1cd164b31f 100644 --- a/src/control/controlobject.h +++ b/src/control/controlobject.h @@ -151,9 +151,15 @@ class ControlObject : public QObject { // You need to use Qt::DirectConnection for the engine objects, since the // audio thread has no Qt event queue. But be a ware of race conditions in this case. // ref: http://qt-project.org/doc/qt-4.8/qt.html#ConnectionType-enum - bool connectValueChangeRequest(const QObject* receiver, - std::function<void(double)> method, - Qt::ConnectionType type = Qt::AutoConnection); + template <typename Receiver, typename Slot> + bool connectValueChangeRequest(Receiver receiver, Slot func, + Qt::ConnectionType type = Qt::AutoConnection) { + bool ret = false; + if (m_pControl) { + ret = m_pControl->connectValueChangeRequest(receiver, func, type); + } + return ret; + } // Installs a value-change request handler that ignores all sets. void setReadOnly(); diff --git a/src/control/controlproxy.cpp b/src/control/controlproxy.cpp index 1e4f6530ee..9434ed6e71 100644 --- a/src/control/controlproxy.cpp +++ b/src/control/controlproxy.cpp @@ -35,140 +35,3 @@ ControlProxy::~ControlProxy() { //qDebug() << "ControlProxy::~ControlProxy()"; } -bool ControlProxy::connectValueChanged(const QObject* receiver, - std::function<void(double)> method, Qt::ConnectionType requestedConnectionType) { - - if (!m_pControl) { - return false; - } - - // We connect to the - // ControlObjectPrivate only once and in a way that - // the requested ConnectionType is working as desired. - // We try to avoid direct connections if not requested - // since you cannot safely delete an object with a pending - // direct connection. This fixes bug Bug #1406124 - // requested: Auto -> COP = Auto / SCO = Auto - // requested: Direct -> COP = Direct / SCO = Direct - // requested: Queued -> COP = Queued / SCO = Auto - // requested: BlockingQueued -> Assert(false) - - std::function<void(double)> copSlot; - Qt::ConnectionType copConnection; - Qt::ConnectionType scoConnection; - switch(requestedConnectionType) { - case Qt::AutoConnection: - copSlot = [=](double value){slotValueChangedAuto(value, this);}; - copConnection = Qt::AutoConnection; - scoConnection = Qt::AutoConnection; - break; - case Qt::DirectConnection: - copSlot = [=](double value){slotValueChangedDirect(value, this);}; - copConnection = Qt::DirectConnection; - scoConnection = Qt::DirectConnection; - break; - case Qt::QueuedConnection: - copSlot = [=](double value){slotValueChangedQueued(value, this);}; - copConnection = Qt::QueuedConnection; - scoConnection = Qt::AutoConnection; - break; - case Qt::BlockingQueuedConnection: - // We must not block the signal source by a blocking connection - DEBUG_ASSERT(false); - return false; - default: - DEBUG_ASSERT(false); - return false; - } - - if (!connect(this, &ControlProxy::valueChanged, receiver, method, scoConnection)) { - return false; - } - - // Connect to ControlObjectPrivate only if required. Do not allow - // duplicate connections. - - // use only explicit direct connection if requested - // the caller must not delete this until the all signals are - // processed to avoid segfaults - connect(m_pControl.data(), &ControlDoublePrivate::valueChanged, - this, copSlot, - static_cast<Qt::ConnectionType>(copConnection | Qt::UniqueConnection)); - return true; -} - -bool ControlProxy::connectValueChanged(const QObject* receiver, - const char* method, Qt::ConnectionType requestedConnectionType) { - - if (!m_pControl) { - return false; - } - - // We connect to the - // ControlObjectPrivate only once and in a way that - // the requested ConnectionType is working as desired. - // We try to avoid direct connections if not requested - // since you cannot safely delete an object with a pending - // direct connection. This fixes bug Bug #1406124 - // requested: Auto -> COP = Auto / SCO = Auto - // requested: Direct -> COP = Direct / SCO = Direct - // requested: Queued -> COP = Queued / SCO = Auto - // requested: BlockingQueued -> Assert(false) - - const char* copSlot; - Qt::ConnectionType copConnection; - Qt::ConnectionType scoConnection; - switch(requestedConnectionType) { - case Qt::AutoConnection: - copSlot = SLOT(slotValueChangedAuto(double, QObject*)); - copConnection = Qt::AutoConnection; - scoConnection = Qt::AutoConnection; - break; - case Qt::DirectConnection: - copSlot = SLOT(slotValueChangedDirect(double, QObject*)); - copConnection = Qt::DirectConnection; - scoConnection = Qt::DirectConnection; - break; - case Qt::QueuedConnection: - copSlot = SLOT(slotValueChangedQueued(double, QObject*)); - copConnection = Qt::QueuedConnection; - scoConnection = Qt::AutoConnection; - break; - case Qt::BlockingQueuedConnection: - // We must not block the signal source by a blocking connection - DEBUG_ASSERT(false); - return false; - default: - DEBUG_ASSERT(false); - return false; - } - - if (!connect((QObject*)this, SIGNAL(valueChanged(double)), - receiver, method, scoConnection)) { - return false; - } - - // Connect to ControlObjectPrivate only if required. Do not allow - // duplicate connections. - - // use only explicit direct connection if requested - // the caller must not delete this until the all signals are - // processed to avoid segfaults - connect(m_pControl.data(), SIGNAL(valueChanged(double, QObject*)), - this, copSlot, - static_cast<Qt::ConnectionType>(copConnection | Qt::UniqueConnection)); - return true; -} - -// connect to parent object -bool ControlProxy::connectValueChanged( - std::function<void(double)> method, Qt::ConnectionType type) { - DEBUG_ASSERT(parent() != NULL); - return connectValueChanged(parent(), method, type); -} - -bool ControlProxy::connectValueChanged( - const char* method, Qt::ConnectionType type) { - DEBUG_ASSERT(parent() != NULL); - return connectValueChanged(parent(), method, type); -} diff --git a/src/control/controlproxy.h b/src/control/controlproxy.h index a619cd0af6..4c72cce95a 100644 --- a/src/control/controlproxy.h +++ b/src/control/controlproxy.h @@ -30,17 +30,72 @@ class ControlProxy : public QObject { return m_key; } - bool connectValueChanged(const QObject* receiver, - std::function<void(double)> method, Qt::ConnectionType type = Qt::AutoConnection); - // for legacy SLOT syntax from Qt < 5. TODO: replace all uses with Qt 5 functor syntax - bool connectValueChanged(const QObject* receiver, - const char* method, Qt::ConnectionType type = Qt::AutoConnection); - - bool connectValueChanged( - std::function<void(double)> method, Qt::ConnectionType type = Qt::AutoConnection); - // for legacy SLOT syntax from Qt < 5. TODO: replace all uses with Qt 5 functor syntax - bool connectValueChanged( - const char* method, Qt::ConnectionType type = Qt::AutoConnection); + template <typename Receiver, typename Slot> + bool connectValueChanged(Receiver receiver, + Slot func, Qt::ConnectionType requestedConnectionType = Qt::AutoConnection) { + if (!m_pControl) { + return false; + } + + // We connect to the + // ControlObjectPrivate only once and in a way that + // the requested ConnectionType is working as desired. + // We try to avoid direct connections if not requested + // since you cannot safely delete an object with a pending + // direct connection. This fixes bug Bug #1406124 + // requested: Auto -> COP = Auto / SCO = Auto + // requested: Direct -> COP = Direct / SCO = Direct + // requested: Queued -> COP = Queued / SCO = Auto + // requested: BlockingQueued -> Assert(false) + + auto copSlot = &ControlProxy::slotValueChangedAuto; + Qt::ConnectionType copConnection; + Qt::ConnectionType scoConnection; + switch(requestedConnectionType) { + case Qt::AutoConnection: + copConnection = Qt::AutoConnection; + scoConnection = Qt::AutoConnection; + break; + case Qt::DirectConnection: + copSlot = &ControlProxy::slotValueChangedDirect; + copConnection = Qt::DirectConnection; + scoConnection = Qt::DirectConnection; + break; + case Qt::QueuedConnection: + copSlot = &ControlProxy::slotValueChangedQueued; + copConnection = Qt::QueuedConnection; + scoConnection = Qt::AutoConnection; + break; + case Qt::BlockingQueuedConnection: + // We must not block the signal source by a blocking connection + DEBUG_ASSERT(false); + return false; + default: + DEBUG_ASSERT(false); + return false; + } + + if (!connect(this, &ControlProxy::valueChanged, receiver, func, scoConnection)) { + return false; + } + + // Connect to ControlObjectPrivate only if required. Do not allow + // duplicate connections. + + // use only explicit direct connection if requested + // the caller must not delete this until the all signals are + // processed to avoid segfaults + connect(m_pControl.data(), &ControlDoublePrivate::valueChanged, + this, copSlot, + static_cast<Qt::ConnectionType>(copConnection | Qt::UniqueConnection)); + return true; + } + // TODO: get the compiler to accept parent() for the receiver + //template <typename Slot> + //bool connectValueChanged(Slot func, Qt::ConnectionType type = Qt::AutoConnection) { + // DEBUG_ASSERT(parent() != nullptr); + // return connectValueChanged(parent(), func, type); + //} // Called from update(); virtual void emitValueChanged() { diff --git a/src/controllers/midi/midioutputhandler.cpp b/src/controllers/midi/midioutputhandler.cpp index 0a69509cc2..6c3a045f65 100644 --- a/src/controllers/midi/midioutputhandler.cpp +++ b/src/controllers/midi/midioutputhandler.cpp @@ -19,7 +19,7 @@ MidiOutputHandler::MidiOutputHandler(MidiController* controller, m_mapping(mapping), m_cos(mapping.controlKey, this), m_lastVal(-1) { // -1 = virgin - m_cos.connectValueChanged(SLOT(controlChanged(double))); + m_cos.connectValueChanged(this, &MidiOutputHandler::controlChanged); } MidiOutputHandler::~MidiOutputHandler() { diff --git a/src/controllers/midi/midioutputhandler.h b/src/controllers/midi/midioutputhandler.h index c28ea8d3b6..9b1230b8e5 100644 --- a/src/controllers/midi/midioutputhandler.h +++ b/src/controllers/midi/midioutputhandler.h @@ -16,7 +16,7 @@ class MidiController; -class MidiOutputHandler : QObject { +class MidiOutputHandler : public QObject { Q_OBJECT public: MidiOutputHandler(MidiController* controller, diff --git a/src/effects/effectparameterslot.cpp b/src/effects/effectparameterslot.cpp index 7650aa2a47..d229d34176 100644 --- a/src/effects/effectparameterslot.cpp +++ b/src/effects/effectparameterslot.cpp @@ -31,7 +31,7 @@ EffectParameterSlot::EffectParameterSlot(const QString& group, const unsigned in m_pControlLinkType->setStates( static_cast<double>(EffectManifestParameter::LinkType::NUM_LINK_TYPES)); m_pControlLinkType->connectValueChangeRequest( - this, [=](double value){slotLinkTypeChanging(value);}); + this, &EffectParameterSlot::slotLinkTypeChanging); m_pControlLinkInverse = new ControlPushButton( ConfigKey(m_group, itemPrefix + QString("_link_inverse"))); diff --git a/src/engine/bpmcontrol.cpp b/src/engine/bpmcontrol.cpp index e1240d85ef..013fe53213 100644 --- a/src/engine/bpmcontrol.cpp +++ b/src/engine/bpmcontrol.cpp @@ -38,14 +38,14 @@ BpmControl::BpmControl(QString group, m_pPlayButton = new ControlProxy(group, "play", this); m_pReverseButton = new ControlProxy(group, "reverse", this); m_pRateSlider = new ControlProxy(group, "rate", this); - m_pRateSlider->connectValueChanged([=](double value){slotUpdateEngineBpm();}, + m_pRateSlider->connectValueChanged(this, &BpmControl::slotUpdateEngineBpm, Qt::DirectConnection); m_pQuantize = ControlObject::getControl(group, "quantize"); m_pRateRange = new ControlProxy(group, "rateRange", this); - m_pRateRange->connectValueChanged([=](double value){slotUpdateRateSlider();}, + m_pRateRange->connectValueChanged(this, &BpmControl::slotUpdateRateSlider, Qt::DirectConnection); m_pRateDir = new ControlProxy(group, "rate_dir", this); - m_pRateDir->connectValueChanged([=](double value){slotUpdateEngineBpm();}, + m_pRateDir->connectValueChanged(this, &BpmControl::slotUpdateEngineBpm, Qt::DirectConnection); m_pPrevBeat.reset(new ControlProxy(group, "beat_prev")); @@ -733,13 +733,15 @@ double BpmControl::getPhaseOffset(double dThisPosition) { return dNewPlaypos - dThisPosition; } -void BpmControl::slotUpdateEngineBpm() { +void BpmControl::slotUpdateEngineBpm(double value) { + Q_UNUSED(value); // Adjust playback bpm in response to a change in the rate slider. double dRate = calcRateRatio(); m_pEngineBpm->set(m_pLocalBpm->get() * dRate); } -void BpmControl::slotUpdateRateSlider() { +void BpmControl::slotUpdateRateSlider(double value) { + Q_UNUSED(value); // Adjust rate slider position to reflect change in rate range. double localBpm = m_pLocalBpm->get(); double rateScale = m_pRateDir->get() * m_pRateRange->get(); diff --git a/src/engine/bpmcontrol.h b/src/engine/bpmcontrol.h index 5d53225aed..a715179ee0 100644 --- a/src/engine/bpmcontrol.h +++ b/src/engine/bpmcontrol.h @@ -83,8 +83,8 @@ class BpmControl : public EngineControl { void slotControlBeatSyncTempo(double); void slotTapFilter(double,int); void slotBpmTap(double); - void slotUpdateRateSlider(); - void slotUpdateEngineBpm(); + void slotUpdateRateSlider(double v = 0.0); + void slotUpdateEngineBpm(double v = 0.0); void slotUpdatedTrackBeats(); void slotBeatsTranslate(double); void slotBeatsTranslateMatchAlignment(double); diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp index 6759bab800..1a7687230b 100644 --- a/src/engine/enginebuffer.cpp +++ b/src/engine/enginebuffer.cpp @@ -108,7 +108,7 @@ EngineBuffer::EngineBuffer(QString group, UserSettingsPointer pConfig, m_playButton = new ControlPushButton(ConfigKey(m_group, "play")); m_playButton->setButtonMode(ControlPushButton::TOGGLE); m_playButton->connectValueChangeRequest( - this, [=](double value){slotControlPlayRequest(value);}, + this, &EngineBuffer::slotControlPlayRequest, Qt::DirectConnection); //Play from Start Button (for sampler) @@ -167,7 +167,7 @@ EngineBuffer::EngineBuffer(QString group, UserSettingsPointer pConfig, m_pSampleRate = new ControlProxy("[Master]", "samplerate", this); m_pKeylockEngine = new ControlProxy("[Master]", "keylock_engine", this); - m_pKeylockEngine->connectValueChanged(SLOT(slotKeylockEngineChanged(double)), + m_pKeylockEngine->connectValueChanged(this, &EngineBuffer::slotKeylockEngineChanged, Qt::DirectConnection); m_pTrackSamples = new ControlObject(ConfigKey(m_group, "track_samples")); @@ -252,7 +252,7 @@ EngineBuffer::EngineBuffer(QString group, UserSettingsPointer pConfig, m_bScalerChanged = true; m_pPassthroughEnabled = new ControlProxy(group, "passthrough", this); - m_pPassthroughEnabled->connectValueChanged(SLOT(slotPassthroughChanged(double)), + m_pPassthroughEnabled->connectValueChanged(this, &EngineBuffer::slotPassthroughChanged, Qt::DirectConnection); #ifdef __SCALER_DEBUG__ diff --git a/src/engine/enginedelay.cpp b/src/engine/enginedelay.cpp index b1846beb64..71bc49b302 100644 --- a/src/engine/enginedelay.cpp +++ b/src/engine/enginedelay.cpp @@ -39,7 +39,7 @@ EngineDelay::EngineDelay(const char* group, ConfigKey delayControl, bool bPersis SLOT(slotDelayChanged()), Qt::DirectConnection); m_pSampleRate = new ControlProxy(group, "samplerate", this); - m_pSampleRate->connectValueChanged(SLOT(slotDelayChanged()), Qt::DirectConnection); + m_pSampleRate->connectValueChanged(this, &EngineDelay::slotDelayChanged, Qt::DirectConnection); } EngineDelay::~EngineDelay() { diff --git a/src/engine/enginetalkoverducking.cpp b/src/engine/enginetalkoverducking.cpp index 290db999fd..803f5f51d8 100644 --- a/src/engine/enginetalkoverducking.cpp +++ b/src/engine/enginetalkoverducking.cpp @@ -9,7 +9,7 @@ EngineTalkoverDucking::EngineTalkoverDucking( m_pConfig(pConfig), m_group(group) { m_pMasterSampleRate = new ControlProxy(m_group, "samplerate", this); - m_pMasterSampleRate->connectValueChanged(SLOT(slotSampleRateChanged(double)), + m_pMasterSampleRate->connectValueChanged(this, &EngineTalkoverDucking::slotSampleRateChanged, Qt::DirectConnection); m_pDuckStrength = new ControlPotmeter(ConfigKey(m_group, "duckStrength"), 0.0, 1.0); diff --git a/src/engine/keycontrol.cpp b/src/engine/keycontrol.cpp index 4924783f74..2d648e4f39 100644 --- a/src/engine/keycontrol.cpp +++ b/src/engine/keycontrol.cpp @@ -28,8 +28,8 @@ KeyControl::KeyControl(QString group, m_pPitch->setStepCount(12); // Fine adjust with semitone / 10 = 10 ct;. m_pPitch->setSmallStepCount(120); - connect(m_pPitch, SIGNAL(valueChanged(double)), - this, SLOT(slotPitchChanged(double)), + connect(m_pPitch, &ControlObject::valueChanged, + this, &KeyControl::slotPitchChanged, Qt::DirectConnection); // pitch_adjust is the distance to the linear pitch in semitones @@ -40,34 +40,34 @@ KeyControl::KeyControl(QString group, m_pPitchAdjust->setStepCount(6); // Fine adjust with semitone / 10 = 10 ct;. m_pPitchAdjust->setSmallStepCount(60); - connect(m_pPitchAdjust, SIGNAL(valueChanged(double)), - this, SLOT(slotPitchAdjustChanged(double)), + connect(m_pPitchAdjust, &ControlObject::valueChanged, + this, &KeyControl::slotPitchAdjustChanged, Qt::DirectConnection); m_pButtonSyncKey = new ControlPushButton(ConfigKey(group, "sync_key")); - connect(m_pButtonSyncKey, SIGNAL(valueChanged(double)), - this, SLOT(slotSyncKey(double)), + connect(m_pButtonSyncKey, &ControlObject::valueChanged, + this, &KeyControl::slotSyncKey, Qt::DirectConnection); m_pButtonResetKey = new ControlPushButton(ConfigKey(group, "reset_key")); - connect(m_pButtonResetKey, SIGNAL(valueChanged(double)), - this, SLOT(slotResetKey(double)), + connect(m_pButtonResetKey, &ControlObject::valueChanged, + this, &KeyControl::slotResetKey, Qt::DirectConnection); m_pFileKey = new ControlObject(ConfigKey(group, "file_key")); - connect(m_pFileKey, SIGNAL(valueChanged(double)), - this, SLOT(slotFileKeyChanged(double)), + connect(m_pFileKey, &ControlObject::valueChanged, + this, &KeyControl::slotFileKeyChanged, Qt::DirectConnection); m_pEngineKey = new ControlObject(ConfigKey(group, "key")); - connect(m_pEngineKey, SIGNAL(valueChanged(double)), - this, SLOT(slotSetEngineKey(double)), + connect(m_pEngineKey, &ControlObject::valueChanged, + this, &KeyControl::slotSetEngineKey, Qt::DirectConnection); m_pEngineKeyDistance = new ControlPotmeter(ConfigKey(group, "visual_key_distance"), -0.5, 0.5); - connect(m_pEngineKeyDistance, SIGNAL(valueChanged(double)), - this, SLOT(slotSetEngineKeyDistance(double)), + connect(m_pEngineKeyDistance, &ControlObject::valueChanged, + this, &KeyControl::slotSetEngineKeyDistance, Qt::DirectConnection); m_keylockMode = new ControlPushButton(ConfigKey(group, "keylockMode")); @@ -78,27 +78,27 @@ KeyControl::KeyControl(QString group, // In case of vinyl control "rate" is a filtered mean value for display m_pRateSlider = new ControlProxy(group, "rate", this); - m_pRateSlider->connectValueChanged(SLOT(slotRateChanged()), + m_pRateSlider->connectValueChanged(this, &KeyControl::slotRateChanged, Qt::DirectConnection); m_pRateRange = new ControlProxy(group, "rateRange", this); - m_pRateRange->connectValueChanged(SLOT(slotRateChanged()), + m_pRateRange->connectValueChanged(this, &KeyControl::slotRateChanged, Qt::DirectConnection); m_pRateDir = new ControlProxy(group, "rate_dir", this); - m_pRateDir->connectValueChanged(SLOT(slotRateChanged()), + m_pRateDir->connectValueChanged(this, &KeyControl::slotRateChanged, Qt::DirectConnection); m_pVCEnabled = new ControlProxy(group, "vinylcontrol_enabled", this); - m_pVCEnabled->connectValueChanged(SLOT(slotRateChanged()), + m_pVCEnabled->connectValueChanged(this, &KeyControl::slotRateChanged, Qt::DirectConnection); m_pVCRate = new ControlProxy(group, "vinylcontr |