summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitattributes26
-rw-r--r--build/debian/changelog6
-rw-r--r--src/controllers/controlpickermenu.cpp6
-rw-r--r--src/engine/controls/bpmcontrol.cpp42
-rw-r--r--src/engine/controls/bpmcontrol.h3
-rw-r--r--src/engine/controls/ratecontrol.cpp357
-rw-r--r--src/engine/controls/ratecontrol.h65
-rw-r--r--src/engine/enginebuffer.h1
-rw-r--r--src/engine/enginemaster.cpp11
-rw-r--r--src/engine/enginemaster.h3
-rw-r--r--src/engine/sync/basesyncablelistener.cpp23
-rw-r--r--src/engine/sync/basesyncablelistener.h20
-rw-r--r--src/engine/sync/enginesync.cpp83
-rw-r--r--src/engine/sync/enginesync.h19
-rw-r--r--src/engine/sync/internalclock.cpp3
-rw-r--r--src/engine/sync/syncable.h26
-rw-r--r--src/engine/sync/synccontrol.cpp54
-rw-r--r--src/engine/sync/synccontrol.h2
-rw-r--r--src/mixer/basetrackplayer.cpp12
-rw-r--r--src/mixer/basetrackplayer.h2
-rw-r--r--src/test/enginebuffertest.cpp69
-rw-r--r--src/test/enginesynctest.cpp104
22 files changed, 515 insertions, 422 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000..0076522bf9
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,26 @@
+# Execute the following command in your local project
+# directory to exclude localization files from merges
+# across branches:
+#
+# $ git config --global merge.ours.driver true
+#
+# This command sets a shell script that is used for all
+# merge=ours files. In this case the script "true" does
+# not touch anything, just returns successful.
+#
+# Background: Localization files from external sources like
+# Transifex must not be merged between release branches and
+# should be ignore while merging! Instead those files are
+# updated by re-importing them manually from the external
+# source. This workflow is supported by configuring the merge
+# strategy for the local Git repository appropriately, i.e.
+# by excluding those files from merging and always keeping the
+# files from the current/target branch (= "ours").
+
+# Exclude Transifex files from merging
+/res/translations/*.ts merge=ours
+/res/translations/*.qm merge=ours
+
+# Exclude WiX translations from merging
+/build/wix/Localization/po/*.po merge=ours
+/build/wix/Localization/po/*.wxl merge=ours
diff --git a/build/debian/changelog b/build/debian/changelog
index 7be287a008..435098f0d8 100644
--- a/build/debian/changelog
+++ b/build/debian/changelog
@@ -1,3 +1,9 @@
+mixxx (2.1.6-0ubuntu1) bionic; urgency=medium
+
+ * New upstream release
+
+ -- Daniel <daniel@daniel-530U3C-530U4C-532U3C> Sun, 23 Dec 2018 11:01:23 +0100
+
mixxx (2.1.4-0ubuntu1) bionic; urgency=medium
* New upstream release.
diff --git a/src/controllers/controlpickermenu.cpp b/src/controllers/controlpickermenu.cpp
index a989d3af43..16e41e8952 100644
--- a/src/controllers/controlpickermenu.cpp
+++ b/src/controllers/controlpickermenu.cpp
@@ -457,6 +457,12 @@ ControlPickerMenu::ControlPickerMenu(QWidget* pParent)
tr("Quick Effect Super Knob (control linked effect parameters)"),
tr("Quick Effect"),
quickEffectMenu);
+ addPrefixedControl(QString("[QuickEffectRack1_[Channel%1]_Effect1]").arg(i),
+ "enabled",
+ tr("Deck %1 Quick Effect Enable Button").arg(i),
+ tr("Quick Effect Enable Button"),
+ tr("Quick Effect"),
+ quickEffectMenu);
}
const int kNumEffectRacks = 1;
diff --git a/src/engine/controls/bpmcontrol.cpp b/src/engine/controls/bpmcontrol.cpp
index 0ff25ec230..328ca718b6 100644
--- a/src/engine/controls/bpmcontrol.cpp
+++ b/src/engine/controls/bpmcontrol.cpp
@@ -148,11 +148,11 @@ double BpmControl::getBpm() const {
return m_pEngineBpm->get();
}
-void BpmControl::slotFileBpmChanged(double bpm) {
- Q_UNUSED(bpm);
+void BpmControl::slotFileBpmChanged(double file_bpm) {
// Adjust the file-bpm with the current setting of the rate to get the
// engine BPM. We only do this for SYNC_NONE decks because EngineSync will
// set our BPM if the file BPM changes. See SyncControl::fileBpmChanged().
+ //qDebug() << "BpmControl::slotFileBpmChanged" << file_bpm;
BeatsPointer pBeats = m_pBeats;
if (pBeats) {
const double beats_bpm =
@@ -161,13 +161,10 @@ void BpmControl::slotFileBpmChanged(double bpm) {
if (beats_bpm != -1) {
m_pLocalBpm->set(beats_bpm);
} else {
- m_pLocalBpm->set(bpm);
+ m_pLocalBpm->set(file_bpm);
}
} else {
- m_pLocalBpm->set(bpm);
- }
- if (getSyncMode() == SYNC_NONE) {
- slotUpdateEngineBpm();
+ m_pLocalBpm->set(file_bpm);
}
resetSyncAdjustment();
}
@@ -271,8 +268,8 @@ bool BpmControl::syncTempo() {
double fOtherBpm = pOtherEngineBuffer->getBpm();
double fOtherLocalBpm = pOtherEngineBuffer->getLocalBpm();
- //qDebug() << "this" << "bpm" << fThisBpm << "filebpm" << fThisFileBpm;
- //qDebug() << "other" << "bpm" << fOtherBpm << "filebpm" << fOtherFileBpm;
+ //qDebug() << "this" << "bpm" << fThisBpm << "filebpm" << fThisLocalBpm;
+ //qDebug() << "other" << "bpm" << fOtherBpm << "filebpm" << fOtherLocalBpm;
////////////////////////////////////////////////////////////////////////////
// Rough proof of how syncing works -- rryan 3/2011
@@ -587,8 +584,11 @@ double BpmControl::getNearestPositionInPhase(
if (!pBeats) {
return dThisPosition;
}
+
+ SyncMode syncMode = getSyncMode();
+
// Master buffer is always in sync!
- if (getSyncMode() == SYNC_MASTER) {
+ if (syncMode == SYNC_MASTER) {
return dThisPosition;
}
@@ -614,24 +614,26 @@ double BpmControl::getNearestPositionInPhase(
}
double dOtherBeatFraction;
- if (getSyncMode() == SYNC_FOLLOWER) {
+ if (syncMode == SYNC_FOLLOWER) {
// If we're a follower, it's easy to get the other beat fraction
dOtherBeatFraction = m_dSyncTargetBeatDistance.getValue();
} else {
// If not, we have to figure it out
EngineBuffer* pOtherEngineBuffer = pickSyncTarget();
- if (pOtherEngineBuffer == NULL) {
- return dThisPosition;
- }
-
if (playing) {
- // "this" track is playing, or just starting
- // only match phase if the sync target is playing as well
- if (pOtherEngineBuffer->getSpeed() == 0.0) {
- return dThisPosition;
+ if (!pOtherEngineBuffer || pOtherEngineBuffer->getSpeed() == 0.0) {
+ // "this" track is playing, or just starting
+ // only match phase if the sync target is playing as well
+ // else use the previouse phase of "this" track before the seek
+ pOtherEngineBuffer = getEngineBuffer();
}
}
+ if (!pOtherEngineBuffer) {
+ // no suitable sync buffer found
+ return dThisPosition;
+ }
+
TrackPointer otherTrack = pOtherEngineBuffer->getLoadedTrack();
BeatsPointer otherBeats = otherTrack ? otherTrack->getBeats() : BeatsPointer();
@@ -830,7 +832,7 @@ double BpmControl::updateLocalBpm() {
double BpmControl::updateBeatDistance() {
double beat_distance = getBeatDistance(getSampleOfTrack().current);
m_pThisBeatDistance->set(beat_distance);
- if (getSyncMode() == SYNC_NONE) {
+ if (!isSynchronized()) {
m_dUserOffset.setValue(0.0);
}
return beat_distance;
diff --git a/src/engine/controls/bpmcontrol.h b/src/engine/controls/bpmcontrol.h
index b802e8f353..15291134b1 100644
--- a/src/engine/controls/bpmcontrol.h
+++ b/src/engine/controls/bpmcontrol.h
@@ -93,6 +93,9 @@ class BpmControl : public EngineControl {
SyncMode getSyncMode() const {
return syncModeFromDouble(m_pSyncMode->get());
}
+ inline bool isSynchronized() const {
+ return toSynchronized(getSyncMode());
+ }
bool syncTempo();
double calcSyncAdjustment(double my_percentage, bool userTweakingSync);
double calcRateRatio() const;
diff --git a/src/engine/controls/ratecontrol.cpp b/src/engine/controls/ratecontrol.cpp
index e51ec0a69d..9faa6422a5 100644
--- a/src/engine/controls/ratecontrol.cpp
+++ b/src/engine/controls/ratecontrol.cpp
@@ -32,12 +32,9 @@ RateControl::RateControl(QString group,
UserSettingsPointer pConfig)
: EngineControl(group, pConfig),
m_pBpmControl(NULL),
- m_ePbCurrent(0),
- m_ePbPressed(0),
m_bTempStarted(false),
- m_dRateTemp(0.0),
- m_eRampBackMode(RATERAMP_RAMPBACK_NONE),
- m_dRateTempRampbackChange(0.0) {
+ m_tempRateRatio(0.0),
+ m_dRateTempRampChange(0.0) {
m_pScratchController = new PositionScratchController(group);
m_pRateDir = new ControlObject(ConfigKey(group, "rate_dir"));
@@ -81,54 +78,39 @@ RateControl::RateControl(QString group,
m_pVCMode = ControlObject::getControl(ConfigKey(getGroup(), "vinylcontrol_mode"));
// Permanent rate-change buttons
- buttonRatePermDown =
+ m_pButtonRatePermDown =
new ControlPushButton(ConfigKey(group,"rate_perm_down"));
- connect(buttonRatePermDown, &ControlObject::valueChanged,
+ connect(m_pButtonRatePermDown, &ControlObject::valueChanged,
this, &RateControl::slotControlRatePermDown,
Qt::DirectConnection);
- buttonRatePermDownSmall =
+ m_pButtonRatePermDownSmall =
new ControlPushButton(ConfigKey(group,"rate_perm_down_small"));
- connect(buttonRatePermDownSmall, &ControlObject::valueChanged,
+ connect(m_pButtonRatePermDownSmall, &ControlObject::valueChanged,
this, &RateControl::slotControlRatePermDownSmall,
Qt::DirectConnection);
- buttonRatePermUp =
+ m_pButtonRatePermUp =
new ControlPushButton(ConfigKey(group,"rate_perm_up"));
- connect(buttonRatePermUp, &ControlObject::valueChanged,
+ connect(m_pButtonRatePermUp, &ControlObject::valueChanged,
this, &RateControl::slotControlRatePermUp,
Qt::DirectConnection);
- buttonRatePermUpSmall =
+ m_pButtonRatePermUpSmall =
new ControlPushButton(ConfigKey(group,"rate_perm_up_small"));
- connect(buttonRatePermUpSmall, &ControlObject::valueChanged,
+ connect(m_pButtonRatePermUpSmall, &ControlObject::valueChanged,
this, &RateControl::slotControlRatePermUpSmall,
Qt::DirectConnection);
// Temporary rate-change buttons
- buttonRateTempDown =
+ m_pButtonRateTempDown =
new ControlPushButton(ConfigKey(group,"rate_temp_down"));
- connect(buttonRateTempDown, &ControlObject::valueChanged,
- this, &RateControl::slotControlRateTempDown,
- Qt::DirectConnection);
-
- buttonRateTempDownSmall =
+ m_pButtonRateTempDownSmall =
new ControlPushButton(ConfigKey(group,"rate_temp_down_small"));
- connect(buttonRateTempDownSmall, &ControlObject::valueChanged,
- this, &RateControl::slotControlRateTempDownSmall,
- Qt::DirectConnection);
-
- buttonRateTempUp =
+ m_pButtonRateTempUp =
new ControlPushButton(ConfigKey(group,"rate_temp_up"));
- connect(buttonRateTempUp, &ControlObject::valueChanged,
- this, &RateControl::slotControlRateTempUp,
- Qt::DirectConnection);
-
- buttonRateTempUpSmall =
+ m_pButtonRateTempUpSmall =
new ControlPushButton(ConfigKey(group,"rate_temp_up_small"));
- connect(buttonRateTempUpSmall, &ControlObject::valueChanged,
- this, &RateControl::slotControlRateTempUpSmall,
- Qt::DirectConnection);
// We need the sample rate so we can guesstimate something close
// what latency is.
@@ -184,14 +166,14 @@ RateControl::~RateControl() {
delete m_pForwardButton;
delete m_pBackButton;
- delete buttonRateTempDown;
- delete buttonRateTempDownSmall;
- delete buttonRateTempUp;
- delete buttonRateTempUpSmall;
- delete buttonRatePermDown;
- delete buttonRatePermDownSmall;
- delete buttonRatePermUp;
- delete buttonRatePermUpSmall;
+ delete m_pButtonRateTempDown;
+ delete m_pButtonRateTempDownSmall;
+ delete m_pButtonRateTempUp;
+ delete m_pButtonRateTempUpSmall;
+ delete m_pButtonRatePermDown;
+ delete m_pButtonRatePermDownSmall;
+ delete m_pButtonRatePermUp;
+ delete m_pButtonRatePermUpSmall;
delete m_pWheel;
delete m_pScratch2;
@@ -280,111 +262,53 @@ void RateControl::slotReverseRollActivate(double v) {
}
}
-void RateControl::slotControlFastForward(double v)
-{
+void RateControl::slotControlFastForward(double v) {
//qDebug() << "slotControlFastForward(" << v << ")";
- if (v==0.)
- m_pRateSearch->set(0.);
- else
- m_pRateSearch->set(4.);
+ if (v > 0.0) {
+ m_pRateSearch->set(4.0);
+ } else {
+ m_pRateSearch->set(0.0);
+ }
}
-void RateControl::slotControlFastBack(double v)
-{
+void RateControl::slotControlFastBack(double v) {
//qDebug() << "slotControlFastBack(" << v << ")";
- if (v==0.)
- m_pRateSearch->set(0.);
- else
- m_pRateSearch->set(-4.);
+ if (v > 0.0) {
+ m_pRateSearch->set(-4.0);
+ } else {
+ m_pRateSearch->set(0.0);
+ }
}
-void RateControl::slotControlRatePermDown(double)
-{
+void RateControl::slotControlRatePermDown(double v) {
// Adjusts temp rate down if button pressed
- if (buttonRatePermDown->get()) {
+ if (v > 0.0) {
m_pRateSlider->set(m_pRateSlider->get() -
- m_pRateDir->get() * m_dPermanentRateChangeCoarse.getValue() / (100 * m_pRateRange->get()));
+ m_pRateDir->get() * m_dPermanentRateChangeCoarse.getValue() / (100 * m_pRateRange->get()));
}
}
-void RateControl::slotControlRatePermDownSmall(double)
-{
+void RateControl::slotControlRatePermDownSmall(double v) {
// Adjusts temp rate down if button pressed
- if (buttonRatePermDownSmall->get())
+ if (v > 0.0) {
m_pRateSlider->set(m_pRateSlider->get() -
- m_pRateDir->get() * m_dPermanentRateChangeFine.getValue() / (100. * m_pRateRange->get()));
+ m_pRateDir->get() * m_dPermanentRateChangeFine.getValue() / (100. * m_pRateRange->get()));
+ }
}
-void RateControl::slotControlRatePermUp(double)
-{
+void RateControl::slotControlRatePermUp(double v) {
// Adjusts temp rate up if button pressed
- if (buttonRatePermUp->get()) {
+ if (v > 0.0) {
m_pRateSlider->set(m_pRateSlider->get() +
- m_pRateDir->get() * m_dPermanentRateChangeCoarse.getValue() / (100. * m_pRateRange->get()));
+ m_pRateDir->get() * m_dPermanentRateChangeCoarse.getValue() / (100. * m_pRateRange->get()));
}
}
-void RateControl::slotControlRatePermUpSmall(double)
-{
+void RateControl::slotControlRatePermUpSmall(double v) {
// Adjusts temp rate up if button pressed
- if (buttonRatePermUpSmall->get())
+ if (v > 0.0) {
m_pRateSlider->set(m_pRateSlider->get() +
- m_pRateDir->get() * m_dPermanentRateChangeFine.getValue() / (100. * m_pRateRange->get()));
-}
-
-void RateControl::slotControlRateTempDown(double)
-{
- // Set the state of the Temporary button. Logic is handled in ::process()
- if (buttonRateTempDown->get() && !(m_ePbPressed & RateControl::RATERAMP_DOWN))
- {
- m_ePbPressed |= RateControl::RATERAMP_DOWN;
- m_ePbCurrent = RateControl::RATERAMP_DOWN;
- }
- else if (!buttonRateTempDown->get())
- {
- m_ePbPressed &= ~RateControl::RATERAMP_DOWN;
- m_ePbCurrent = m_ePbPressed;
- }
-}
-
-void RateControl::slotControlRateTempDownSmall(double)
-{
- // Set the state of the Temporary button. Logic is handled in ::process()
- if (buttonRateTempDownSmall->get() && !(m_ePbPressed & RateControl::RATERAMP_DOWN))
- {
- m_ePbPressed |= RateControl::RATERAMP_DOWN;
- m_ePbCurrent = RateControl::RATERAMP_DOWN;
- }
- else if (!buttonRateTempDownSmall->get())
- {
- m_ePbPressed &= ~RateControl::RATERAMP_DOWN;
- m_ePbCurrent = m_ePbPressed;
- }
-}
-
-void RateControl::slotControlRateTempUp(double)
-{
- // Set the state of the Temporary button. Logic is handled in ::process()
- if (buttonRateTempUp->get() && !(m_ePbPressed & RateControl::RATERAMP_UP))
- {
- m_ePbPressed |= RateControl::RATERAMP_UP;
- m_ePbCurrent = RateControl::RATERAMP_UP;
- }
- else if (!buttonRateTempUp->get())
- {
- m_ePbPressed &= ~RateControl::RATERAMP_UP;
- m_ePbCurrent = m_ePbPressed;
- }
-}
-
-void RateControl::slotControlRateTempUpSmall(double) {
- // Set the state of the Temporary button. Logic is handled in ::process()
- if (buttonRateTempUpSmall->get() && !(m_ePbPressed & RateControl::RATERAMP_UP)){
- m_ePbPressed |= RateControl::RATERAMP_UP;
- m_ePbCurrent = RateControl::RATERAMP_UP;
- } else if (!buttonRateTempUpSmall->get()) {
- m_ePbPressed &= ~RateControl::RATERAMP_UP;
- m_ePbCurrent = m_ePbPressed;
+ m_pRateDir->get() * m_dPermanentRateChangeFine.getValue() / (100. * m_pRateRange->get()));
}
}
@@ -427,6 +351,9 @@ double RateControl::calculateSpeed(double baserate, double speed, bool paused,
bool* pReportReverse) {
*pReportScratching = false;
*pReportReverse = false;
+
+ processTempRate(iSamplesPerBuffer);
+
double rate = (paused ? 0 : 1.0);
double searching = m_pRateSearch->get();
if (searching) {
@@ -477,7 +404,8 @@ double RateControl::calculateSpeed(double baserate, double speed, bool paused,
if (useScratch2Value) {
rate = scratchFactor;
} else {
- rate = speed + getTempRate();
+ // add temp rate, but don't go backwards
+ rate = math_max(speed + getTempRate(), 0.0);
rate += wheelFactor;
}
rate += jogFactor;
@@ -523,134 +451,101 @@ double RateControl::calculateSpeed(double baserate, double speed, bool paused,
return rate;
}
-void RateControl::process(const double rate,
- const double currentSample,
- const int bufferSamples)
-{
- Q_UNUSED(rate);
- Q_UNUSED(currentSample);
- /*
- * Code to handle temporary rate change buttons.
- *
- * We support two behaviors, the standard ramped pitch bending
- * and pitch shift stepping, which is the old behavior.
- */
-
- /*
- * Initialize certain values necessary for pitchbending. Most of this
- * code should be handled inside a slot, but we'd need to connect to
- * the troublesome Latency ControlObject... Either the Master or Soundcard
- * one.
- */
-
- double latrate = ((double)bufferSamples / (double)m_pSampleRate->get());
-
-
- if ((m_ePbPressed) && (!m_bTempStarted)) {
- m_bTempStarted = true;
+void RateControl::processTempRate(const int bufferSamples) {
+ // Code to handle temporary rate change buttons.
+ // We support two behaviors, the standard ramped pitch bending
+ // and pitch shift stepping, which is the old behavior.
+
+ RampDirection rampDirection = RampDirection::None;
+ if (m_pButtonRateTempUp->toBool()) {
+ rampDirection = RampDirection::Up;
+ } else if (m_pButtonRateTempDown->toBool()) {
+ rampDirection = RampDirection::Down;
+ } else if (m_pButtonRateTempUpSmall->toBool()) {
+ rampDirection = RampDirection::UpSmall;
+ } else if (m_pButtonRateTempDownSmall->toBool()) {
+ rampDirection = RampDirection::DownSmall;
+ }
+ if (rampDirection != RampDirection::None) {
if (m_eRateRampMode == RampMode::Stepping) {
- // old temporary pitch shift behavior
- double range = m_pRateRange->get();
-
- // Avoid Division by Zero
- if (range == 0) {
- qDebug() << "Avoiding a Division by Zero in RATERAMP_STEP code";
- return;
+ if (!m_bTempStarted) {
+ m_bTempStarted = true;
+ // old temporary pitch shift behavior
+ double change = m_dTemporaryRateChangeCoarse.getValue() / 100.0;
+ double csmall = m_dTemporaryRateChangeFine.getValue() / 100.0;
+
+ switch (rampDirection) {
+ case RampDirection::Up:
+ setRateTemp(change);
+ break;
+ case RampDirection::Down:
+ setRateTemp(-change);
+ break;
+ case RampDirection::UpSmall:
+ setRateTemp(csmall);
+ break;
+ case RampDirection::DownSmall:
+ setRateTemp(-csmall);
+ break;
+ case RampDirection::None:
+ default:
+ DEBUG_ASSERT(false);
+ }
}
-
- double change = m_pRateDir->get() * m_dTemporaryRateChangeCoarse.getValue() /
- (100. * range);
- double csmall = m_pRateDir->get() * m_dTemporaryRateChangeFine.getValue() /
- (100. * range);
-
- if (buttonRateTempUp->get())
- addRateTemp(change);
- else if (buttonRateTempDown->get())
- subRateTemp(change);
- else if (buttonRateTempUpSmall->get())
- addRateTemp(csmall);
- else if (buttonRateTempDownSmall->get())
- subRateTemp(csmall);
} else if (m_eRateRampMode == RampMode::Linear) {
- m_dTemporaryRateChangeCoarse.setValue(
- ((double)latrate / ((double)m_iRateRampSensitivity / 100.)));
-
- if (m_eRampBackMode == RATERAMP_RAMPBACK_PERIOD)
- m_dRateTempRampbackChange = 0.0;
- }
-
- }
+ if (rampDirection != RampDirection::None) {
+ if (!m_bTempStarted) {
+ m_bTempStarted = true;
+ double latrate = ((double)bufferSamples / (double)m_pSampleRate->get());
+ m_dRateTempRampChange = (latrate / ((double)m_iRateRampSensitivity / 100.));
+ }
- if (m_eRateRampMode == RampMode::Linear) {
- if (m_ePbCurrent) {
- // apply ramped pitchbending
- if (m_ePbCurrent == RateControl::RATERAMP_UP) {
- addRateTemp(m_dTemporaryRateChangeCoarse.getValue());
- } else if (m_ePbCurrent == RateControl::RATERAMP_DOWN) {
- subRateTemp(m_dTemporaryRateChangeCoarse.getValue());
- }
- } else if ((m_bTempStarted)
- || ((m_eRampBackMode != RATERAMP_RAMPBACK_NONE)
- && (m_dRateTemp != 0.0))) {
- // No buttons pressed, so time to deinitialize
- m_bTempStarted = false;
-
- if ((m_eRampBackMode == RATERAMP_RAMPBACK_PERIOD)
- && (m_dRateTempRampbackChange == 0.0)) {
- int period = 2;
- m_dRateTempRampbackChange = fabs(
- m_dRateTemp / period);
- } else if ((m_eRampBackMode != RATERAMP_RAMPBACK_NONE)
- && (m_dRateTempRampbackChange == 0.0)) {
- if (fabs(m_dRateTemp) < m_dRateTempRampbackChange) {
- resetRateTemp();
- } else if (m_dRateTemp > 0) {
- subRateTemp(m_dRateTempRampbackChange);
- } else {
- addRateTemp(m_dRateTempRampbackChange);
+ switch (rampDirection) {
+ case RampDirection::Up:
+ case RampDirection::UpSmall:
+ addRateTemp(m_dRateTempRampChange * m_pRateRange->get());
+ break;
+ case RampDirection::Down:
+ case RampDirection::DownSmall:
+ subRateTemp(m_dRateTempRampChange * m_pRateRange->get());
+ break;
+ case RampDirection::None:
+ default:
+ DEBUG_ASSERT(false);
}
- } else {
- resetRateTemp();
}
}
- } else if ((m_eRateRampMode == RampMode::Stepping) && (m_bTempStarted)) {
- if (!m_ePbCurrent) {
- m_bTempStarted = false;
- resetRateTemp();
- }
+ } else if (m_bTempStarted) {
+ m_bTempStarted = false;
+ resetRateTemp();
}
}
double RateControl::getTempRate() {
- return (m_pRateDir->get() * (m_dRateTemp * m_pRateRange->get()));
-}
-
-void RateControl::setRateTemp(double v)
-{
- // Do not go backwards
- if ((calcRateRatio() + v) < 0) {
- return;
- }
-
- m_dRateTemp = v;
- if (m_dRateTemp < -1.0) {
- m_dRateTemp = -1.0;
- } else if (m_dRateTemp > 1.0) {
- m_dRateTemp = 1.0;
- } else if (isnan(m_dRateTemp)) {
- m_dRateTemp = 0;
+ // qDebug() << m_tempRateRatio;
+ return m_tempRateRatio;
+}
+
+void RateControl::setRateTemp(double v) {
+ m_tempRateRatio = v;
+ if (m_tempRateRatio < -1.0) {
+ m_tempRateRatio = -1.0;
+ } else if (m_tempRateRatio > 1.0) {
+ m_tempRateRatio = 1.0;
+ } else if (isnan(m_tempRateRatio)) {
+ m_tempRateRatio = 0;
}
}
void RateControl::addRateTemp(double v)
{
- setRateTemp(m_dRateTemp + v);
+ setRateTemp(m_tempRateRatio + v);
}
void RateControl::subRateTemp(double v)
{
- setRateTemp(m_dRateTemp - v);
+ setRateTemp(m_tempRateRatio - v);
}
void RateControl::resetRateTemp(void)
diff --git a/src/engine/controls/ratecontrol.h b/src/engine/controls/ratecontrol.h
index 97ea85c5b8..8bbc7acb55 100644
--- a/src/engine/controls/ratecontrol.h
+++ b/src/engine/controls/ratecontrol.h
@@ -36,11 +36,12 @@ public:
// Enumerations which hold the state of the pitchbend buttons.
// These enumerations can be used like a bitmask.
- enum RATERAMP_DIRECTION {
- RATERAMP_NONE = 0, // No buttons are held down
- RATERAMP_DOWN = 1, // Down button is being held
- RATERAMP_UP = 2, // Up button is being held
- RATERAMP_BOTH = 3 // Both buttons are being held down
+ enum class RampDirection {
+ None, // No buttons are held down
+ Down, // Down button is being held
+ Up, // Up button is being held
+ DownSmall, // DownSmall button is being held
+ UpSmall, // UpSmall button is being held
};
enum class RampMode {
@@ -48,23 +49,8 @@ public:
Linear = 1 // pitch moves up/down in a progressively linear fashion
};
- // This defines how the rate returns to normal. Currently unused.
- // Rate ramp back mode:
- // RATERAMP_RAMPBACK_NONE: returns back to normal all at once.
- // RATERAMP_RAMPBACK_SPEED: moves back in a linearly progressive manner.
- // RATERAMP_RAMPBACK_PERIOD: returns to normal within a period of time.
- enum RATERAMP_RAMPBACK_MODE {
- RATERAMP_RAMPBACK_NONE,
- RATERAMP_RAMPBACK_SPEED,
- RATERAMP_RAMPBACK_PERIOD
- };
-
void setBpmControl(BpmControl* bpmcontrol);
- // Must be called during each callback of the audio thread so that
- // RateControl has a chance to update itself.
- void process(const double dRate,
- const double currentSample,
- const int bufferSamples) override;
+
// Returns the current engine rate. "reportScratching" is used to tell
// the caller that the user is currently scratching, and this is used to
// disable keylock.
@@ -99,14 +85,11 @@ public:
void slotControlRatePermDownSmall(double);
void slotControlRatePermUp(double);
void slotControlRatePermUpSmall(double);
- void slotControlRateTempDown(double);
- void slotControlRateTempDownSmall(double);
- void slotControlRateTempUp(double);
- void slotControlRateTempUpSmall(double);
void slotControlFastForward(double);
void slotControlFastBack(double);
private:
+ void processTempRate(const int bufferSamples);
double getJogFactor() const;
double getWheelFactor() const;
SyncMode getSyncMode() const;
@@ -128,18 +111,18 @@ public:
static ControlValueAtomic<double> m_dPermanentRateChangeCoarse;
static ControlValueAtomic<double> m_dPermanentRateChangeFine;
- ControlPushButton *buttonRateTempDown;
- ControlPushButton *buttonRateTempDownSmall;
- ControlPushButton *buttonRateTempUp;
- ControlPushButton *buttonRateTempUpSmall;
+ ControlPushButton* m_pButtonRateTempDown;
+ ControlPushButton* m_pButtonRateTempDownSmall;
+ ControlPushButton* m_pButtonRateTempUp;
+ ControlPushButton* m_pButtonRateTempUpSmall;
- ControlPushButton *buttonRatePermDown;
- ControlPushButton *buttonRatePermDownSmall;
- ControlPushButton *buttonRatePermUp;
- ControlPushButton *buttonRatePermUpSmall;
+ ControlPushButton* m_pButtonRatePermDown;
+ ControlPushButton* m_pButtonRatePermDownSmall;
+ ControlPushButton* m_pButtonRatePermUp;
+ ControlPushButton* m_pButtonRatePermUpSmall;
- ControlObject *m_pRateDir;
- ControlObject *m_pRateRange;
+ ControlObject* m_pRateDir;
+ ControlObject* m_pRateRange;
ControlPotmeter* m_pRateSlider;
ControlPotmeter* m_pRateSearch;
ControlPushButton* m_pReverseButton;
@@ -167,11 +150,6 @@ public:
ControlProxy* m_pSyncMode;
ControlProxy* m_pSlipEnabled;
- // The current rate ramping direction. Only holds the last button pressed.
- int m_ePbCurrent;
- // The rate ramping buttons which are currently being pressed.
- int m_ePbPressed;
-
// This is true if we've already started to ramp the rate
bool m_bTempStarted;
// Set the Temporary Rate Change Mode
@@ -183,10 +161,9 @@ public:
// Factor applied to jogwheels when the track is paused to speed up seeking.
static const double kPausedJogMultiplier;
// Temporary pitchrate, added to the permanent rate for calculateRate
- double m_dRateTemp;
- enum RATERAMP_RAMPBACK_MODE m_eRampBackMode;
- // Return speed for temporary rate change
- double m_dRateTempRampbackChange;
+ double m_tempRateRatio;
+ // Speed for temporary rate change
+ double m_dRateTempRampChange;
};
#endif /* RATECONTROL_H */
diff --git a/src/engine/enginebuffer.h b/src/engine/enginebuffer.h
index 36a6975880..4b0a4f4f16 100644
--- a/src/engine/enginebuffer.h
+++ b/src/engine/enginebuffer.h
@@ -358,6 +358,7 @@ class EngineBuffer : public EngineObject {
FRIEND_TEST(EngineBufferTest, ResetPitchAdjustUsesLinear);
FRIEND_TEST(EngineBufferTest, VinylScalerRampZero);
FRIEND_TEST(EngineBufferTest, ReadFadeOut);
+ FRIEND_TEST(EngineBufferTest, RateTempTest);
EngineBufferScale* m_pScaleVinyl;
// The keylock engine is configurable, so it could flip flop between
// ScaleST and ScaleRB during a single callback.
diff --git a/src/engine/enginemaster.cpp b/src/engine/enginemaster.cpp
index c0a94426f4..8d2afe2829 100644
--- a/src/engine/enginemaster.cpp
+++ b/src/engine/enginemaster.cpp
@@ -289,7 +289,8 @@ void EngineMaster::processChannels(int iBufferSize) {
continue;
}
- if (pChannel->isTalkoverEnabled()) {
+ if (pChannel->isTalkoverEnabled() &&
+ !pChannelInfo->m_pMuteControl->toBool()) {
// talkover is an exclusive channel
// once talkover is enabled it is not used in
// xFader-Mix
@@ -449,10 +450,10 @@ void EngineMaster::process(const int iBufferSize) {
// Mix all the talkover enabled channels together.
// Effects processing is done in place to avoid unnecessary buffer copying.