Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EngineBuffer: Add const & order methods #2997

Merged
merged 2 commits into from
Aug 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 100 additions & 93 deletions src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,13 +304,8 @@ EngineBuffer::~EngineBuffer() {
qDeleteAll(m_engineControls);
}

double EngineBuffer::fractionalPlayposFromAbsolute(double absolutePlaypos) {
double fFractionalPlaypos = 0.0;
if (m_trackSamplesOld) {
fFractionalPlaypos = math_min<double>(absolutePlaypos, m_trackSamplesOld);
fFractionalPlaypos /= m_trackSamplesOld;
}
return fFractionalPlaypos;
void EngineBuffer::bindWorkers(EngineWorkerScheduler* pWorkerScheduler) {
m_pReader->setScheduler(pWorkerScheduler);
}

void EngineBuffer::enableIndependentPitchTempoScaling(bool bEnable,
Expand Down Expand Up @@ -348,12 +343,11 @@ void EngineBuffer::enableIndependentPitchTempoScaling(bool bEnable,
}
}

double EngineBuffer::getBpm()
{
double EngineBuffer::getBpm() const {
return m_pBpmControl->getBpm();
}

double EngineBuffer::getLocalBpm() {
double EngineBuffer::getLocalBpm() const {
return m_pBpmControl->getLocalBpm();
}

Expand Down Expand Up @@ -467,18 +461,22 @@ void EngineBuffer::setNewPlaypos(double newpos) {
verifyPlay(); // verify or update play button and indicator
}

QString EngineBuffer::getGroup() {
QString EngineBuffer::getGroup() const {
return m_group;
}

double EngineBuffer::getSpeed() {
double EngineBuffer::getSpeed() const {
return m_speed_old;
}

bool EngineBuffer::getScratching() {
bool EngineBuffer::getScratching() const {
return m_scratching_old;
}

bool EngineBuffer::isReverse() const {
return m_reverse_old;
}

// WARNING: Always called from the EngineWorker thread pool
void EngineBuffer::slotTrackLoading() {
// Pause EngineBuffer from processing frames
Expand Down Expand Up @@ -509,19 +507,22 @@ void EngineBuffer::slotTrackLoaded(TrackPointer pTrack,
kLogger.trace() << getGroup() << "EngineBuffer::slotTrackLoaded";
}
TrackPointer pOldTrack = m_pCurrentTrack;

m_pause.lock();

m_visualPlayPos->setInvalid();
m_filepos_play = DBL_MIN; // for execute seeks to 0.0

m_pCurrentTrack = pTrack;
m_pTrackSamples->set(iTrackNumSamples);
m_pTrackSampleRate->set(iTrackSampleRate);
m_pTrackLoaded->forceSet(1);

// Reset slip mode
m_pSlipButton->set(0);
m_bSlipEnabledProcessing = false;
m_dSlipPosition = 0.;
m_dSlipRate = 0;
m_pTrackLoaded->forceSet(1);

// Reset the pitch value for the new track.
m_pause.unlock();

Expand All @@ -541,39 +542,64 @@ void EngineBuffer::slotTrackLoadFailed(TrackPointer pTrack,
emit trackLoadFailed(pTrack, reason);
}

TrackPointer EngineBuffer::getLoadedTrack() const {
return m_pCurrentTrack;
}

bool EngineBuffer::isReverse() {
return m_reverse_old;
}

void EngineBuffer::ejectTrack() {
// clear track values in any case, this may fix Bug #1450424
// clear track values in any case, may fix https://bugs.launchpad.net/mixxx/+bug/1450424
if (kLogger.traceEnabled()) {
kLogger.trace() << "EngineBuffer::ejectTrack()";
}
TrackPointer pOldTrack = m_pCurrentTrack;
m_pause.lock();
m_iTrackLoading = 0;
m_pTrackLoaded->forceSet(0);
m_pTrackSamples->set(0);
m_pTrackSampleRate->set(0);

m_visualPlayPos->set(0.0, 0.0, 0.0, 0.0, 0.0);
TrackPointer pTrack = m_pCurrentTrack;
doSeekPlayPos(0.0, SEEK_EXACT);

m_pCurrentTrack.reset();
m_pTrackSamples->set(0);
m_pTrackSampleRate->set(0);
m_pTrackLoaded->forceSet(0);

m_playButton->set(0.0);
m_playposSlider->set(0);
m_pCueControl->resetIndicators();
doSeekPlayPos(0.0, SEEK_EXACT);

m_pause.unlock();

// Close open file handles by unloading the current track
m_pReader->newTrack(TrackPointer());

if (pTrack) {
notifyTrackLoaded(TrackPointer(), pTrack);
if (pOldTrack) {
notifyTrackLoaded(TrackPointer(), pOldTrack);
}
m_iTrackLoading = 0;
}

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::slotPassthroughChanged(double enabled) {
Expand All @@ -598,6 +624,15 @@ void EngineBuffer::slotControlSeekExact(double playPosition) {
doSeekPlayPos(playPosition, SEEK_EXACT);
}

double EngineBuffer::fractionalPlayposFromAbsolute(double absolutePlaypos) {
double fFractionalPlaypos = 0.0;
if (m_trackSamplesOld) {
fFractionalPlaypos = math_min<double>(absolutePlaypos, m_trackSamplesOld);
fFractionalPlaypos /= m_trackSamplesOld;
}
return fFractionalPlaypos;
}

void EngineBuffer::doSeekFractional(double fractionalPos, enum SeekRequest seekType) {
// Prevent NaN's from sneaking into the engine.
if (isnan(fractionalPos)) {
Expand Down Expand Up @@ -1143,7 +1178,7 @@ void EngineBuffer::processSyncRequests() {

void EngineBuffer::processSeek(bool paused) {
// Check if we are cloning another channel before doing any seeking.
EngineChannel* pChannel = m_pChannelToCloneFrom.fetchAndStoreRelaxed(NULL);
EngineChannel* pChannel = m_pChannelToCloneFrom.fetchAndStoreRelaxed(nullptr);
if (pChannel) {
seekCloneBuffer(pChannel->getEngineBuffer());
}
Expand Down Expand Up @@ -1238,6 +1273,16 @@ void EngineBuffer::postProcess(const int iBufferSize) {
updateIndicators(m_speed_old, iBufferSize);
}

bool EngineBuffer::getQueuedSeekPosition(double* pSeekPosition) const {
bool isSeekQueued = m_iSeekQueued.loadAcquire() != SEEK_NONE;
if (isSeekQueued) {
*pSeekPosition = m_queuedSeekPosition.getValue();
} else {
*pSeekPosition = -1;
}
return isSeekQueued;
}

void EngineBuffer::updateIndicators(double speed, int iBufferSize) {
if (!m_trackSampleRateOld) {
// This happens if Deck Passthrough is active but no track is loaded.
Expand Down Expand Up @@ -1327,25 +1372,15 @@ void EngineBuffer::addControl(EngineControl* pControl) {
pControl->setEngineBuffer(this);
}

void EngineBuffer::bindWorkers(EngineWorkerScheduler* pWorkerScheduler) {
m_pReader->setScheduler(pWorkerScheduler);
}

bool EngineBuffer::isTrackLoaded() {
bool EngineBuffer::isTrackLoaded() const {
if (m_pCurrentTrack) {
return true;
}
return false;
}

bool EngineBuffer::getQueuedSeekPosition(double* pSeekPosition) {
bool isSeekQueued = m_iSeekQueued.loadAcquire() != SEEK_NONE;
if (isSeekQueued) {
*pSeekPosition = m_queuedSeekPosition.getValue();
} else {
*pSeekPosition = -1;
}
return isSeekQueued;
TrackPointer EngineBuffer::getLoadedTrack() const {
return m_pCurrentTrack;
}

void EngineBuffer::slotEjectTrack(double v) {
Expand All @@ -1359,7 +1394,7 @@ void EngineBuffer::slotEjectTrack(double v) {
}
}

double EngineBuffer::getExactPlayPos() {
double EngineBuffer::getExactPlayPos() const {
double visualPlayPos = getVisualPlayPos();
if (visualPlayPos > 0) {
return getVisualPlayPos() * getTrackSamples();
Expand All @@ -1370,65 +1405,25 @@ double EngineBuffer::getExactPlayPos() {
}
}

double EngineBuffer::getVisualPlayPos() {
double EngineBuffer::getVisualPlayPos() const {
return m_visualPlayPos->getEnginePlayPos();
}

double EngineBuffer::getTrackSamples() {
double EngineBuffer::getTrackSamples() const {
return m_pTrackSamples->get();
}

void EngineBuffer::setScalerForTest(EngineBufferScale* pScaleVinyl,
EngineBufferScale* pScaleKeylock) {
m_pScaleVinyl = pScaleVinyl;
m_pScaleKeylock = pScaleKeylock;
m_pScale = m_pScaleVinyl;
m_pScale->clear();
m_bScalerChanged = true;
// This bool is permanently set and can't be undone.
m_bScalerOverride = true;
}

void EngineBuffer::collectFeatures(GroupFeatureState* pGroupFeatures) const {
if (m_pBpmControl != NULL) {
m_pBpmControl->collectFeatures(pGroupFeatures);
}
}

double EngineBuffer::getRateRatio() const {
if (m_pBpmControl != NULL) {
if (m_pBpmControl != nullptr) {
return m_pBpmControl->getRateRatio();
}
return 1.0;
}

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);
void EngineBuffer::collectFeatures(GroupFeatureState* pGroupFeatures) const {
if (m_pBpmControl != nullptr) {
m_pBpmControl->collectFeatures(pGroupFeatures);
}

// Inform BaseTrackPlayer via a queued connection
emit trackLoaded(pNewTrack, pOldTrack);
}

void EngineBuffer::slotUpdatedTrackBeats() {
Expand All @@ -1439,3 +1434,15 @@ void EngineBuffer::slotUpdatedTrackBeats() {
}
}
}

void EngineBuffer::setScalerForTest(
EngineBufferScale* pScaleVinyl,
EngineBufferScale* pScaleKeylock) {
m_pScaleVinyl = pScaleVinyl;
m_pScaleKeylock = pScaleKeylock;
m_pScale = m_pScaleVinyl;
m_pScale->clear();
m_bScalerChanged = true;
// This bool is permanently set and can't be undone.
m_bScalerOverride = true;
}
38 changes: 18 additions & 20 deletions src/engine/enginebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,15 @@ class EngineBuffer : public EngineObject {

void bindWorkers(EngineWorkerScheduler* pWorkerScheduler);

QString getGroup() const;
// Return the current rate (not thread-safe)
double getSpeed();
bool getScratching();
double getSpeed() const;
bool getScratching() const;
bool isReverse() const;
// Returns current bpm value (not thread-safe)
double getBpm();
double getBpm() const;
// Returns the BPM of the loaded track around the current position (not thread-safe)
double getLocalBpm();
double getLocalBpm() const;
// Sets pointer to other engine buffer/channel
void setEngineMaster(EngineMaster*);

Expand All @@ -138,29 +140,25 @@ class EngineBuffer : public EngineObject {
void processSlip(int iBufferSize);
void postProcess(const int iBufferSize);

QString getGroup();
bool isTrackLoaded();
// return true if a seek is currently cueued but not yet processed, false otherwise
// if no seek was queued, the seek position is set to -1
bool getQueuedSeekPosition(double* pSeekPosition);
TrackPointer getLoadedTrack() const;
/// Return true iff a seek is currently queued but not yet processed
/// If no seek was queued, the seek position is set to -1
bool getQueuedSeekPosition(double* pSeekPosition) const;

bool isReverse();
bool isTrackLoaded() const;
TrackPointer getLoadedTrack() const;

double getExactPlayPos();
double getVisualPlayPos();
double getTrackSamples();

void collectFeatures(GroupFeatureState* pGroupFeatures) const;
double getExactPlayPos() const;
double getVisualPlayPos() const;
double getTrackSamples() const;

double getRateRatio() const;

// For dependency injection of readers.
//void setReader(CachingReader* pReader);
void collectFeatures(GroupFeatureState* pGroupFeatures) const;

// For dependency injection of scalers.
void setScalerForTest(EngineBufferScale* pScaleVinyl,
EngineBufferScale* pScaleKeylock);
void setScalerForTest(
EngineBufferScale* pScaleVinyl,
EngineBufferScale* pScaleKeylock);

// For injection of fake tracks.
void loadFakeTrack(TrackPointer pTrack, bool bPlay);
Expand Down