Skip to content

Commit

Permalink
Implement a direct way to trigger saved loops
Browse files Browse the repository at this point in the history
  • Loading branch information
Holzhaus committed Jun 28, 2019
1 parent b2bf980 commit 68cd170
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 14 deletions.
31 changes: 19 additions & 12 deletions src/engine/controls/cuecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ CueControl::CueControl(QString group,
m_pPrevBeat = ControlObject::getControl(ConfigKey(group, "beat_prev"));
m_pNextBeat = ControlObject::getControl(ConfigKey(group, "beat_next"));
m_pClosestBeat = ControlObject::getControl(ConfigKey(group, "beat_closest"));
m_pLoopStartPosition = ControlObject::getControl(ConfigKey(group, "loop_start_position"));
m_pLoopEndPosition = ControlObject::getControl(ConfigKey(group, "loop_end_position"));
m_pLoopStartPosition = new ControlProxy(group, "loop_start_position");
m_pLoopEndPosition = new ControlProxy(group, "loop_end_position");
m_pLoopEnabled = new ControlProxy(group, "loop_enabled");

m_pCuePoint = new ControlObject(ConfigKey(group, "cue_point"));
m_pCuePoint->set(-1.0);
Expand Down Expand Up @@ -906,8 +907,7 @@ void CueControl::savedLoopActivate(SavedLoopControl* pControl, double v) {
int position = pCue->getPosition();
int length = pCue->getLength();
if (position != -1 && length > 0) {
m_pLoopStartPosition->set(position);
m_pLoopEndPosition->set(position + length);
setLoop(position, position + length, false);
} else {
savedLoopSet(pControl, v);
}
Expand All @@ -921,25 +921,32 @@ void CueControl::savedLoopActivate(SavedLoopControl* pControl, double v) {
}

void CueControl::savedLoopReloop(SavedLoopControl* pControl, double v) {
if (!v)
return;

savedLoopActivate(pControl, v);
//qDebug() << "CueControl::savedLoopReloop" << v;

QMutexLocker lock(&m_mutex);

if (!m_pLoadedTrack) {
return;
}

CuePointer pCue(pControl->getCue());

// Need to unlock before emitting any signals to prevent deadlock.
lock.unlock();

if (pCue) {
int position = pCue->getPosition();
if (position != -1) {
seekAbs(position);
if (v) {
int position = pCue->getPosition();
int length = pCue->getLength();
if (position != -1 && length > 0) {
setLoop(position, position + length, true);
} else {
savedLoopSet(pControl, v);
}
}
} else {
if (v) {
// just in case
savedLoopSet(pControl, v);
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/engine/controls/cuecontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,9 @@ class CueControl : public EngineControl {
ControlObject* m_pPrevBeat;
ControlObject* m_pNextBeat;
ControlObject* m_pClosestBeat;
ControlObject* m_pLoopStartPosition;
ControlObject* m_pLoopEndPosition;
ControlProxy* m_pLoopStartPosition;
ControlProxy* m_pLoopEndPosition;
ControlProxy* m_pLoopEnabled;
bool m_bypassCueSetByPlay;

const int m_iNumHotCues;
Expand Down
6 changes: 6 additions & 0 deletions src/engine/controls/enginecontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ EngineBuffer* EngineControl::getEngineBuffer() {
return m_pEngineBuffer;
}

void EngineControl::setLoop(double startPosition, double endPosition, bool reloop) {
if (m_pEngineBuffer) {
m_pEngineBuffer->setLoop(startPosition, endPosition, reloop);
}
}

void EngineControl::seekAbs(double samplePosition) {
if (m_pEngineBuffer) {
m_pEngineBuffer->slotControlSeekAbs(samplePosition);
Expand Down
2 changes: 2 additions & 0 deletions src/engine/controls/enginecontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class EngineControl : public QObject {
const double dTotalSamples, const double dTrackSampleRate);
QString getGroup() const;

void setLoop(double startPosition, double endPosition, bool reloop);

// Called to collect player features for effects processing.
virtual void collectFeatureState(GroupFeatureState* pGroupFeatures) const {
Q_UNUSED(pGroupFeatures);
Expand Down
26 changes: 26 additions & 0 deletions src/engine/controls/loopingcontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,32 @@ void LoopingControl::hintReader(HintVector* pHintList) {
}
}

void LoopingControl::setLoop(double startPosition, double endPosition, bool reloop) {
qDebug() << "setLoop" << startPosition << endPosition << reloop;

LoopSamples loopSamples = m_loopSamples.getValue();
if (loopSamples.start != startPosition || loopSamples.end != endPosition || loopSamples.seekMode != LoopSeekMode::NONE) {
loopSamples.start = startPosition;
loopSamples.end = endPosition;
loopSamples.seekMode = LoopSeekMode::NONE;

clearActiveBeatLoop();

m_loopSamples.setValue(loopSamples);
m_pCOLoopStartPosition->set(loopSamples.start);
m_pCOLoopEndPosition->set(loopSamples.end);
setLoopingEnabled(true);
} else {
setLoopingEnabled(m_bLoopingEnabled ? reloop : true);
}

if (reloop) {
// seekExact is necessary here to prevent notifySeek() from disabling our loop
seekExact(static_cast<double>(
m_loopSamples.getValue().start));
}
}

void LoopingControl::setLoopInToCurrentPosition() {
// set loop-in position
BeatsPointer pBeats = m_pBeats;
Expand Down
2 changes: 2 additions & 0 deletions src/engine/controls/loopingcontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class LoopingControl : public EngineControl {

void notifySeek(double dNewPlaypos, bool adjustingPhase) override;

void setLoop(double startPosition, double endPosition, bool reloop);

bool isLoopingEnabled();

public slots:
Expand Down
4 changes: 4 additions & 0 deletions src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ double EngineBuffer::getLocalBpm() {
return m_pBpmControl->getLocalBpm();
}

void EngineBuffer::setLoop(double startPosition, double endPosition, bool reloop) {
m_pLoopingControl->setLoop(startPosition, endPosition, reloop);
}

void EngineBuffer::setEngineMaster(EngineMaster* pEngineMaster) {
for (const auto& pControl: qAsConst(m_engineControls)) {
pControl->setEngineMaster(pEngineMaster);
Expand Down
2 changes: 2 additions & 0 deletions src/engine/enginebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class EngineBuffer : public EngineObject {
double getBpm();
// Returns the BPM of the loaded track around the current position (not thread-safe)
double getLocalBpm();
// Sets a loop for the loaded track (not thread safe)
void setLoop(double, double, bool);
// Sets pointer to other engine buffer/channel
void setEngineMaster(EngineMaster*);

Expand Down

0 comments on commit 68cd170

Please sign in to comment.