Skip to content

Commit

Permalink
EngineControl: Use mixxx::audio::FramePos for setLoop()/setBeatLoop()
Browse files Browse the repository at this point in the history
  • Loading branch information
Holzhaus committed Aug 6, 2021
1 parent ff49096 commit 3825b41
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 48 deletions.
14 changes: 5 additions & 9 deletions src/engine/controls/cuecontrol.cpp
Expand Up @@ -934,7 +934,7 @@ void CueControl::hotcueGotoAndLoop(HotcueControl* pControl, double value) {
setCurrentSavedLoopControlAndActivate(pControl);
} else if (pCue->getType() == mixxx::CueType::HotCue) {
seekAbs(startPosition);
setBeatLoop(startPosition.toEngineSamplePos(), true);
setBeatLoop(startPosition, true);
} else {
return;
}
Expand Down Expand Up @@ -976,9 +976,7 @@ void CueControl::hotcueCueLoop(HotcueControl* pControl, double value) {
} else {
bool loopActive = pControl->getStatus() == HotcueControl::Status::Active;
Cue::StartAndEndPositions pos = pCue->getStartAndEndPosition();
setLoop(pos.startPosition.toEngineSamplePosMaybeInvalid(),
pos.endPosition.toEngineSamplePosMaybeInvalid(),
!loopActive);
setLoop(pos.startPosition, pos.endPosition, !loopActive);
}
} break;
case mixxx::CueType::HotCue: {
Expand All @@ -991,7 +989,7 @@ void CueControl::hotcueCueLoop(HotcueControl* pControl, double value) {
startPosition ==
mixxx::audio::FramePos::fromEngineSamplePosMaybeInvalid(
m_pLoopStartPosition->get());
setBeatLoop(startPosition.toEngineSamplePosMaybeInvalid(), !loopActive);
setBeatLoop(startPosition, !loopActive);
break;
}
default:
Expand Down Expand Up @@ -1022,9 +1020,7 @@ void CueControl::hotcueActivate(HotcueControl* pControl, double value, HotcueSet
bool loopActive = pControl->getStatus() ==
HotcueControl::Status::Active;
Cue::StartAndEndPositions pos = pCue->getStartAndEndPosition();
setLoop(pos.startPosition.toEngineSamplePos(),
pos.endPosition.toEngineSamplePos(),
!loopActive);
setLoop(pos.startPosition, pos.endPosition, !loopActive);
}
break;
default:
Expand Down Expand Up @@ -2252,7 +2248,7 @@ void CueControl::setCurrentSavedLoopControlAndActivate(HotcueControl* pControl)
}

// Set new control as active
setLoop(pos.startPosition.toEngineSamplePos(), pos.endPosition.toEngineSamplePos(), true);
setLoop(pos.startPosition, pos.endPosition, true);
pControl->setStatus(HotcueControl::Status::Active);
m_pCurrentSavedLoopControl.storeRelease(pControl);
}
Expand Down
6 changes: 4 additions & 2 deletions src/engine/controls/enginecontrol.cpp
Expand Up @@ -73,13 +73,15 @@ EngineBuffer* EngineControl::getEngineBuffer() {
return m_pEngineBuffer;
}

void EngineControl::setBeatLoop(double startPosition, bool enabled) {
void EngineControl::setBeatLoop(mixxx::audio::FramePos startPosition, bool enabled) {
if (m_pEngineBuffer) {
return m_pEngineBuffer->setBeatLoop(startPosition, enabled);
}
}

void EngineControl::setLoop(double startPosition, double endPosition, bool enabled) {
void EngineControl::setLoop(mixxx::audio::FramePos startPosition,
mixxx::audio::FramePos endPosition,
bool enabled) {
if (m_pEngineBuffer) {
return m_pEngineBuffer->setLoop(startPosition, endPosition, enabled);
}
Expand Down
6 changes: 4 additions & 2 deletions src/engine/controls/enginecontrol.h
Expand Up @@ -62,8 +62,10 @@ class EngineControl : public QObject {
mixxx::audio::SampleRate sampleRate);
QString getGroup() const;

void setBeatLoop(double startPosition, bool enabled);
void setLoop(double startPosition, double endPosition, bool enabled);
void setBeatLoop(mixxx::audio::FramePos startPosition, bool enabled);
void setLoop(mixxx::audio::FramePos startPosition,
mixxx::audio::FramePos endPosition,
bool enabled);

// Called to collect player features for effects processing.
virtual void collectFeatureState(GroupFeatureState* pGroupFeatures) const {
Expand Down
30 changes: 17 additions & 13 deletions src/engine/controls/loopingcontrol.cpp
Expand Up @@ -531,8 +531,8 @@ double LoopingControl::getSyncPositionInsideLoop(double dRequestedPlaypos, doubl
return dSyncedPlayPos;
}

void LoopingControl::setBeatLoop(double startPositionSamples, bool enabled) {
VERIFY_OR_DEBUG_ASSERT(startPositionSamples != Cue::kNoPosition) {
void LoopingControl::setBeatLoop(mixxx::audio::FramePos startPosition, bool enabled) {
VERIFY_OR_DEBUG_ASSERT(startPosition.isValid()) {
return;
}

Expand All @@ -545,25 +545,28 @@ void LoopingControl::setBeatLoop(double startPositionSamples, bool enabled) {

// TODO(XXX): This is not realtime safe. See this Zulip discussion for details:
// https://mixxx.zulipchat.com/#narrow/stream/109171-development/topic/getting.20locks.20out.20of.20Beats
const auto startPosition = mixxx::audio::FramePos::fromEngineSamplePos(startPositionSamples);
const auto endPosition = pBeats->findNBeatsFromPosition(startPosition, beatloopSize);

if (startPosition.isValid() && endPosition.isValid()) {
setLoop(startPositionSamples, endPosition.toEngineSamplePos(), enabled);
if (endPosition.isValid()) {
setLoop(startPosition, endPosition, enabled);
}
}

void LoopingControl::setLoop(double startPosition, double endPosition, bool enabled) {
VERIFY_OR_DEBUG_ASSERT(startPosition != Cue::kNoPosition &&
endPosition != Cue::kNoPosition && startPosition < endPosition) {
void LoopingControl::setLoop(mixxx::audio::FramePos startPosition,
mixxx::audio::FramePos endPosition,
bool enabled) {
VERIFY_OR_DEBUG_ASSERT(startPosition.isValid() && endPosition.isValid() &&
startPosition < endPosition) {
return;
}

const double startPositionSamples = startPosition.toEngineSamplePos();
const double endPositionSamples = endPosition.toEngineSamplePos();

LoopSamples loopSamples = m_loopSamples.getValue();
if (loopSamples.start != startPosition || loopSamples.end != endPosition) {
if (loopSamples.start != startPositionSamples || loopSamples.end != endPositionSamples) {
// Copy saved loop parameters to active loop
loopSamples.start = startPosition;
loopSamples.end = endPosition;
loopSamples.start = startPositionSamples;
loopSamples.end = endPositionSamples;
loopSamples.seekMode = LoopSeekMode::None;
clearActiveBeatLoop();
m_loopSamples.setValue(loopSamples);
Expand All @@ -583,7 +586,8 @@ void LoopingControl::setLoop(double startPosition, double endPosition, bool enab
slotLoopInGoto(1);
}

m_pCOBeatLoopSize->setAndConfirm(findBeatloopSizeForLoop(startPosition, endPosition));
m_pCOBeatLoopSize->setAndConfirm(
findBeatloopSizeForLoop(startPositionSamples, endPositionSamples));
}

void LoopingControl::setLoopInToCurrentPosition() {
Expand Down
6 changes: 4 additions & 2 deletions src/engine/controls/loopingcontrol.h
Expand Up @@ -48,8 +48,10 @@ class LoopingControl : public EngineControl {

void notifySeek(mixxx::audio::FramePos position) override;

void setBeatLoop(double startPosition, bool enabled);
void setLoop(double startPosition, double endPosition, bool enabled);
void setBeatLoop(mixxx::audio::FramePos startPosition, bool enabled);
void setLoop(mixxx::audio::FramePos startPosition,
mixxx::audio::FramePos endPosition,
bool enabled);
void setRateControl(RateControl* rateControl);
bool isLoopingEnabled();

Expand Down
6 changes: 4 additions & 2 deletions src/engine/enginebuffer.cpp
Expand Up @@ -369,11 +369,13 @@ mixxx::Bpm EngineBuffer::getLocalBpm() const {
return m_pBpmControl->getLocalBpm();
}

void EngineBuffer::setBeatLoop(double startPosition, bool enabled) {
void EngineBuffer::setBeatLoop(mixxx::audio::FramePos startPosition, bool enabled) {
return m_pLoopingControl->setBeatLoop(startPosition, enabled);
}

void EngineBuffer::setLoop(double startPosition, double endPositon, bool enabled) {
void EngineBuffer::setLoop(mixxx::audio::FramePos startPosition,
mixxx::audio::FramePos endPositon,
bool enabled) {
return m_pLoopingControl->setLoop(startPosition, endPositon, enabled);
}

Expand Down
6 changes: 4 additions & 2 deletions src/engine/enginebuffer.h
Expand Up @@ -101,9 +101,11 @@ class EngineBuffer : public EngineObject {
/// Returns the BPM of the loaded track around the current position (not thread-safe)
mixxx::Bpm getLocalBpm() const;
/// Sets a beatloop for the loaded track (not thread safe)
void setBeatLoop(double startPosition, bool enabled);
void setBeatLoop(mixxx::audio::FramePos startPosition, bool enabled);
/// Sets a loop for the loaded track (not thread safe)
void setLoop(double startPosition, double endPositon, bool enabled);
void setLoop(mixxx::audio::FramePos startPosition,
mixxx::audio::FramePos endPositon,
bool enabled);
// Sets pointer to other engine buffer/channel
void setEngineMaster(EngineMaster*);

Expand Down
20 changes: 4 additions & 16 deletions src/test/hotcuecontrol_test.cpp
Expand Up @@ -263,10 +263,7 @@ TEST_F(HotcueControlTest, SetLoopAuto) {

constexpr mixxx::audio::FramePos loopStartPosition(100);
constexpr mixxx::audio::FramePos loopEndPosition(200);
m_pChannel1->getEngineBuffer()->setLoop(
loopStartPosition.toEngineSamplePosMaybeInvalid(),
loopEndPosition.toEngineSamplePosMaybeInvalid(),
true);
m_pChannel1->getEngineBuffer()->setLoop(loopStartPosition, loopEndPosition, true);

m_pHotcue1Set->set(1);
m_pHotcue1Set->set(0);
Expand All @@ -288,10 +285,7 @@ TEST_F(HotcueControlTest, SetLoopManualWithLoop) {

constexpr mixxx::audio::FramePos loopStartPosition(100);
constexpr mixxx::audio::FramePos loopEndPosition(200);
m_pChannel1->getEngineBuffer()->setLoop(
loopStartPosition.toEngineSamplePosMaybeInvalid(),
loopEndPosition.toEngineSamplePosMaybeInvalid(),
true);
m_pChannel1->getEngineBuffer()->setLoop(loopStartPosition, loopEndPosition, true);

m_pHotcue1SetLoop->set(1);
m_pHotcue1SetLoop->set(0);
Expand Down Expand Up @@ -674,10 +668,7 @@ TEST_F(HotcueControlTest, SavedLoopStatus) {
constexpr auto loopStartPositon = mixxx::audio::FramePos(100);
constexpr auto loopEndPosition = mixxx::audio::FramePos(200);

m_pChannel1->getEngineBuffer()->setLoop(
loopStartPositon.toEngineSamplePosMaybeInvalid(),
loopEndPosition.toEngineSamplePosMaybeInvalid(),
true);
m_pChannel1->getEngineBuffer()->setLoop(loopStartPositon, loopEndPosition, true);

m_pHotcue1SetLoop->set(1);
m_pHotcue1SetLoop->set(0);
Expand Down Expand Up @@ -1000,10 +991,7 @@ TEST_F(HotcueControlTest, SavedLoopCueLoopWithExistingLoop) {
constexpr auto loopStartPosition = mixxx::audio::FramePos(100);
constexpr auto loopEndPosition = mixxx::audio::FramePos(200);

m_pChannel1->getEngineBuffer()->setLoop(
loopStartPosition.toEngineSamplePos(),
loopEndPosition.toEngineSamplePos(),
true);
m_pChannel1->getEngineBuffer()->setLoop(loopStartPosition, loopEndPosition, true);

m_pHotcue1SetLoop->set(1);
m_pHotcue1SetLoop->set(0);
Expand Down

0 comments on commit 3825b41

Please sign in to comment.