summaryrefslogtreecommitdiffstats
path: root/src/engine/enginebuffer.cpp
diff options
context:
space:
mode:
authorJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-05-07 18:53:18 +0200
committerJan Holthuis <jan.holthuis@ruhr-uni-bochum.de>2020-05-07 18:53:18 +0200
commit134966c7840d32b6d6160e1be1d5e0267c4d7113 (patch)
treeed564d647ad70fce7b5e013476373ea02ed6f6b8 /src/engine/enginebuffer.cpp
parentf76bb5ef62ccc924b3d4c8c8702f4ab0e97456bd (diff)
parent898052f480ddbdefe3a36ce73893b90731f3beb3 (diff)
Merge branch 'master' of github.com:mixxxdj/mixxx into saved-loops
Diffstat (limited to 'src/engine/enginebuffer.cpp')
-rw-r--r--src/engine/enginebuffer.cpp105
1 files changed, 77 insertions, 28 deletions
diff --git a/src/engine/enginebuffer.cpp b/src/engine/enginebuffer.cpp
index 0be7c0e822..c9228891e3 100644
--- a/src/engine/enginebuffer.cpp
+++ b/src/engine/enginebuffer.cpp
@@ -1,16 +1,18 @@
#include "engine/enginebuffer.h"
-#include <cfloat>
-
#include <QtDebug>
+#include <cfloat>
-#include "engine/cachingreader/cachingreader.h"
-#include "preferences/usersettings.h"
#include "control/controlindicator.h"
#include "control/controllinpotmeter.h"
-#include "control/controlproxy.h"
#include "control/controlpotmeter.h"
+#include "control/controlproxy.h"
#include "control/controlpushbutton.h"
+#include "engine/bufferscalers/enginebufferscalelinear.h"
+#include "engine/bufferscalers/enginebufferscalerubberband.h"
+#include "engine/bufferscalers/enginebufferscalest.h"
+#include "engine/cachingreader/cachingreader.h"
+#include "engine/channels/enginechannel.h"
#include "engine/controls/bpmcontrol.h"
#include "engine/controls/clockcontrol.h"
#include "engine/controls/cuecontrol.h"
@@ -19,21 +21,19 @@
#include "engine/controls/loopingcontrol.h"
#include "engine/controls/quantizecontrol.h"
#include "engine/controls/ratecontrol.h"
-#include "engine/bufferscalers/enginebufferscalelinear.h"
-#include "engine/bufferscalers/enginebufferscalerubberband.h"
-#include "engine/bufferscalers/enginebufferscalest.h"
-#include "engine/channels/enginechannel.h"
#include "engine/enginemaster.h"
#include "engine/engineworkerscheduler.h"
#include "engine/readaheadmanager.h"
#include "engine/sync/enginesync.h"
#include "engine/sync/synccontrol.h"
+#include "preferences/usersettings.h"
#include "track/beatfactory.h"
#include "track/keyutils.h"
#include "track/track.h"
#include "util/assert.h"
#include "util/compatibility.h"
#include "util/defs.h"
+#include "util/logger.h"
#include "util/math.h"
#include "util/sample.h"
#include "util/timer.h"
@@ -45,6 +45,7 @@
#endif
namespace {
+const mixxx::Logger kLogger("EngineBuffer");
const double kLinearScalerElipsis = 1.00058; // 2^(0.01/12): changes < 1 cent allows a linear scaler
@@ -194,7 +195,6 @@ EngineBuffer::EngineBuffer(const QString& group,
m_pEngineSync = pMixingEngine->getEngineSync();
m_pSyncControl = new SyncControl(group, pConfig, pChannel, m_pEngineSync);
- addControl(m_pSyncControl);
#ifdef __VINYLCONTROL__
m_pVinylControlControl = new VinylControlControl(group, pConfig);
@@ -216,6 +216,7 @@ EngineBuffer::EngineBuffer(const QString& group,
m_pRateControl->setBpmControl(m_pBpmControl);
m_pSyncControl->setEngineControls(m_pRateControl, m_pBpmControl);
pMixingEngine->getEngineSync()->addSyncableDeck(m_pSyncControl);
+ addControl(m_pSyncControl);
m_fwdButton = ControlObject::getControl(ConfigKey(group, "fwd"));
m_backButton = ControlObject::getControl(ConfigKey(group, "back"));
@@ -412,6 +413,9 @@ void EngineBuffer::requestEnableSync(bool enabled) {
void EngineBuffer::requestSyncMode(SyncMode mode) {
// If we're not playing, the queued event won't get processed so do it now.
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << getGroup() << "EngineBuffer::requestSyncMode";
+ }
if (m_playButton->get() == 0.0) {
m_pEngineSync->requestSyncMode(m_pSyncControl, mode);
} else {
@@ -441,7 +445,9 @@ void EngineBuffer::seekCloneBuffer(EngineBuffer* pOtherBuffer) {
// WARNING: This method is not thread safe and must not be called from outside
// the engine callback!
void EngineBuffer::setNewPlaypos(double newpos) {
- //qDebug() << m_group << "engine new pos " << newpos;
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << m_group << "EngineBuffer::setNewPlaypos" << newpos;
+ }
m_filepos_play = newpos;
@@ -497,15 +503,15 @@ void EngineBuffer::loadFakeTrack(TrackPointer pTrack, bool bPlay) {
}
slotTrackLoaded(pTrack, pTrack->getSampleRate(),
pTrack->getSampleRate() * pTrack->getDurationInt());
- m_pSyncControl->setLocalBpm(pTrack->getBpm());
- m_pSyncControl->trackLoaded(pTrack);
}
// WARNING: Always called from the EngineWorker thread pool
void EngineBuffer::slotTrackLoaded(TrackPointer pTrack,
int iTrackSampleRate,
int iTrackNumSamples) {
- //qDebug() << getGroup() << "EngineBuffer::slotTrackLoaded";
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << getGroup() << "EngineBuffer::slotTrackLoaded";
+ }
TrackPointer pOldTrack = m_pCurrentTrack;
m_pause.lock();
@@ -549,7 +555,9 @@ bool EngineBuffer::isReverse() {
void EngineBuffer::ejectTrack() {
// clear track values in any case, this may fix Bug #1450424
- //qDebug() << "EngineBuffer::ejectTrack()";
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << "EngineBuffer::ejectTrack()";
+ }
m_pause.lock();
m_iTrackLoading = 0;
m_pTrackLoaded->forceSet(0);
@@ -721,6 +729,9 @@ void EngineBuffer::processTrackLocked(
baserate = m_trackSampleRateOld / sample_rate;
}
+ // Sync requests can affect rate, so process those first.
+ processSyncRequests();
+
// Note: play is also active during cue preview
bool paused = !m_playButton->toBool();
KeyControl::PitchTempoRatio pitchTempoRatio = m_pKeyControl->getPitchTempoRatio();
@@ -736,7 +747,6 @@ void EngineBuffer::processTrackLocked(
// Update the slipped position and seek if it was disabled.
processSlip(iBufferSize);
- processSyncRequests();
// Note: This may effects the m_filepos_play, play, scaler and crossfade buffer
processSeek(paused);
@@ -1030,21 +1040,19 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) {
// - Set last sample value (m_fLastSampleValue) so that rampOut works? Other
// miscellaneous upkeep issues.
- int sample_rate = static_cast<int>(m_pSampleRate->get());
+ m_iSampleRate = static_cast<int>(m_pSampleRate->get());
// If the sample rate has changed, force Rubberband to reset so that
// it doesn't reallocate when the user engages keylock during playback.
// We do this even if rubberband is not active.
- if (sample_rate != m_iSampleRate) {
- m_pScaleLinear->setSampleRate(sample_rate);
- m_pScaleST->setSampleRate(sample_rate);
- m_pScaleRB->setSampleRate(sample_rate);
- m_iSampleRate = sample_rate;
- }
+ const auto sampleRate = mixxx::audio::SampleRate(m_iSampleRate);
+ m_pScaleLinear->setSampleRate(sampleRate);
+ m_pScaleST->setSampleRate(sampleRate);
+ m_pScaleRB->setSampleRate(sampleRate);
bool bTrackLoading = atomicLoadRelaxed(m_iTrackLoading) != 0;
if (!bTrackLoading && m_pause.tryLock()) {
- processTrackLocked(pOutput, iBufferSize, sample_rate);
+ processTrackLocked(pOutput, iBufferSize, m_iSampleRate);
// release the pauselock
m_pause.unlock();
} else {
@@ -1077,7 +1085,7 @@ void EngineBuffer::process(CSAMPLE* pOutput, const int iBufferSize) {
}
#endif
- if (m_pSyncControl->getSyncMode() == SYNC_MASTER) {
+ if (isMaster(m_pSyncControl->getSyncMode())) {
// Report our speed to SyncControl immediately instead of waiting
// for postProcess so we can broadcast this update to followers.
m_pSyncControl->reportPlayerSpeed(m_speed_old, m_scratching_old);
@@ -1132,7 +1140,7 @@ void EngineBuffer::processSyncRequests() {
}
if (mode_request != SYNC_INVALID) {
m_pEngineSync->requestSyncMode(m_pSyncControl,
- static_cast<SyncMode>(mode_request));
+ static_cast<SyncMode>(mode_request));
}
}
@@ -1188,11 +1196,22 @@ void EngineBuffer::processSeek(bool paused) {
}
if (!paused && (seekType & SEEK_PHASE)) {
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << "EngineBuffer::processSeek Seeking phase";
+ }
double requestedPosition = position;
double syncPosition = m_pBpmControl->getBeatMatchPosition(position, true, true);
position = m_pLoopingControl->getSyncPositionInsideLoop(requestedPosition, syncPosition);
+ if (kLogger.traceEnabled()) {
+ kLogger.trace()
+ << "EngineBuffer::processSeek seek info: " << m_filepos_play
+ << " " << position;
+ }
}
if (position != m_filepos_play) {
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << "EngineBuffer::processSeek Seek to" << position;
+ }
setNewPlaypos(position);
}
m_iSeekQueued.storeRelease(SEEK_NONE);
@@ -1202,11 +1221,14 @@ void EngineBuffer::postProcess(const int iBufferSize) {
// The order of events here is very delicate. It's necessary to update
// some values before others, because the later updates may require
// values from the first update.
+ if (kLogger.traceEnabled()) {
+ kLogger.trace() << getGroup() << "EngineBuffer::postProcess";
+ }
double local_bpm = m_pBpmControl->updateLocalBpm();
double beat_distance = m_pBpmControl->updateBeatDistance();
m_pSyncControl->setLocalBpm(local_bpm);
SyncMode mode = m_pSyncControl->getSyncMode();
- if (mode == SYNC_MASTER) {
+ if (isMaster(mode)) {
m_pEngineSync->notifyBeatDistanceChanged(m_pSyncControl, beat_distance);
} else if (mode == SYNC_FOLLOWER) {
// Report our speed to SyncControl. If we are master, we already did this.
@@ -1346,7 +1368,7 @@ double EngineBuffer::getExactPlayPos() {
return getVisualPlayPos() * getTrackSamples();
} else {
// Track was just loaded and the first buffer was not processed yet.
- // asume it is at 0:00
+ // assume it is at 0:00
return 0.0;
}
}
@@ -1385,11 +1407,38 @@ double EngineBuffer::getRateRatio() const {
void EngineBuffer::notifyTrackLoaded(
TrackPointer pNewTrack, TrackPointer pOldTrack) {
+ if (pOldTrack) {
+ disconnect(
+ pOldTrack.get(),
+ &Track::beatsUpdated,
+ this,
+ &EngineBuffer::slotUpdatedTrackBeats);
+ }
+
// First inform engineControls directly
// Note: we are still in a worker thread.
for (const auto& pControl: qAsConst(m_engineControls)) {
pControl->trackLoaded(pNewTrack);
}
+
+ if (pNewTrack) {
+ connect(
+ pNewTrack.get(),
+ &Track::beatsUpdated,
+ this,
+ &EngineBuffer::slotUpdatedTrackBeats,
+ Qt::DirectConnection);
+ }
+
// Inform BaseTrackPlayer via a queued connection
emit trackLoaded(pNewTrack, pOldTrack);
}
+
+void EngineBuffer::slotUpdatedTrackBeats() {
+ TrackPointer pTrack = m_pCurrentTrack;
+ if (pTrack) {
+ for (const auto& pControl : qAsConst(m_engineControls)) {
+ pControl->trackBeatsUpdated(pTrack->getBeats());
+ }
+ }
+}