Skip to content

Commit

Permalink
Merge pull request #1987 from daschuer/visualsmanager
Browse files Browse the repository at this point in the history
VisualsManager follow up
  • Loading branch information
daschuer authored Jan 9, 2019
2 parents 9c4a6d3 + 1d62453 commit bcad3df
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 46 deletions.
5 changes: 3 additions & 2 deletions src/engine/enginebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ void EngineBuffer::ejectTrack() {
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;
m_pCurrentTrack.reset();
m_playButton->set(0.0);
Expand Down Expand Up @@ -1179,8 +1180,8 @@ void EngineBuffer::postProcess(const int iBufferSize) {
}

void EngineBuffer::updateIndicators(double speed, int iBufferSize) {
if (!m_trackSampleRateOld || !m_trackSamplesOld) {
// no track loaded
VERIFY_OR_DEBUG_ASSERT(m_trackSampleRateOld && m_trackSamplesOld) {
// no track loaded, function not called in this case
return;
}

Expand Down
66 changes: 28 additions & 38 deletions src/waveform/visualsmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,11 @@
#include "waveform/waveformwidgetfactory.h"
#include "control/controlobject.h"

namespace {

// Rate at which the playpos slider is updated
const int kUpdateRate = 15; // updates per second
// Number of kiUpdateRates that go by before we update BPM.
const int kSlowUpdateDivider = 4; // kUpdateRate / kSlowUpdateDivider = 3.75 updates per sec

} // anonymous namespace

DeckVisuals::DeckVisuals(const QString& group)
: m_group(group),
m_SlowTickCnt(0),
m_trackLoaded(false),
playButton(ConfigKey(group, "play")),
loopEnabled(ConfigKey(group, "loop_enabled")),
engineBpm(ConfigKey(group, "bpm")),
Expand All @@ -27,42 +20,39 @@ DeckVisuals::DeckVisuals(const QString& group)

// Control used to communicate ratio playpos to GUI thread
m_pVisualPlayPos = VisualPlayPosition::getVisualPlayPosition(m_group);

m_cpuTimer.start();
}

// this is called from WaveformWidgetFactory::render in the main thread with the
// configured waveform frame rate
void DeckVisuals::process(double remainingTimeTriggerSeconds) {
if (m_cpuTimer.elapsed() >= mixxx::Duration::fromMillis(1000 / kUpdateRate)) {
m_cpuTimer.restart();

double playPosition;
double tempoTrackSeconds;
m_pVisualPlayPos->getTrackTime(&playPosition, &tempoTrackSeconds);

double timeRemaining = (1.0 - playPosition) * tempoTrackSeconds;
m_pTimeRemaining->set(timeRemaining);
m_pTimeElapsed->set(tempoTrackSeconds - timeRemaining);

if (!playButton.toBool() || // not playing
loopEnabled.toBool() || // in loop
tempoTrackSeconds <= remainingTimeTriggerSeconds || // track too short
timeRemaining > remainingTimeTriggerSeconds // before the trigger
) {
m_pEndOfTrack->set(0.0);
} else {
m_pEndOfTrack->set(1.0);
}
double playPosition;
double tempoTrackSeconds;
m_pVisualPlayPos->getTrackTime(&playPosition, &tempoTrackSeconds);
bool trackLoaded = (tempoTrackSeconds != 0.0);
if (!m_trackLoaded && !trackLoaded) {
return;
}

// m_playposSlider->set(fFractionalPlaypos);
// m_pCueControl->updateIndicators();
double timeRemaining = (1.0 - playPosition) * tempoTrackSeconds;
m_pTimeRemaining->set(timeRemaining);
m_pTimeElapsed->set(tempoTrackSeconds - timeRemaining);

if (!playButton.toBool() || // not playing
loopEnabled.toBool() || // in loop
tempoTrackSeconds <= remainingTimeTriggerSeconds || // track too short
timeRemaining > remainingTimeTriggerSeconds // before the trigger
) {
m_pEndOfTrack->set(0.0);
} else {
m_pEndOfTrack->set(1.0);
}

// Update the BPM even more slowly
m_SlowTickCnt = (m_SlowTickCnt + 1) % kSlowUpdateDivider;
if (m_SlowTickCnt == 0) {
m_pVisualBpm->set(engineBpm.get());
}
m_pVisualKey->set(engineKey.get());
// Update the BPM even more slowly
m_SlowTickCnt = (m_SlowTickCnt + 1) % kSlowUpdateDivider;
if (m_SlowTickCnt == 0 || !trackLoaded) {
m_pVisualBpm->set(engineBpm.get());
}
m_pVisualKey->set(engineKey.get());

m_trackLoaded = trackLoaded;
}
26 changes: 20 additions & 6 deletions src/waveform/visualsmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@
#include "util/performancetimer.h"
#include "waveform/visualplayposition.h"

namespace {

// Rate at which the playpos slider is updated
const int kUpdateRate = 15; // updates per second
// Number of kiUpdateRates that go by before we update BPM.
const int kSlowUpdateDivider = 4; // kUpdateRate / kSlowUpdateDivider = 3.75 updates per sec

} // anonymous namespace

// This class updates the controls used for widgets and
// controler indicator, in a CPU saving way and outside the engine thread
class DeckVisuals {
Expand All @@ -18,9 +27,8 @@ class DeckVisuals {

private:
QString m_group;
PerformanceTimer m_cpuTimer;
mixxx::Duration m_lastUpdateTime;
int m_SlowTickCnt;
bool m_trackLoaded;

std::unique_ptr<ControlObject> m_pTimeElapsed;
std::unique_ptr<ControlObject> m_pTimeRemaining;
Expand All @@ -33,23 +41,29 @@ class DeckVisuals {
ControlProxy engineBpm;
ControlProxy engineKey;

//std::unique_ptr<ControlObject> m_playposSlider;

QSharedPointer<VisualPlayPosition> m_pVisualPlayPos;
};

class VisualsManager {
public:
VisualsManager() {
m_cpuTimer.start();
}

void addDeck(const QString& group) {
m_deckVisuals.push_back(
std::make_unique<DeckVisuals>(group));
}

void process(double remainingTimeTriggerSeconds) {
for (const auto& d: m_deckVisuals) {
d->process(remainingTimeTriggerSeconds);
if (m_cpuTimer.elapsed() >= mixxx::Duration::fromMillis(1000 / kUpdateRate)) {
m_cpuTimer.restart();
for (const auto& d: m_deckVisuals) {
d->process(remainingTimeTriggerSeconds);
}
}
}
private:
std::vector<std::unique_ptr<DeckVisuals> > m_deckVisuals;
PerformanceTimer m_cpuTimer;
};

0 comments on commit bcad3df

Please sign in to comment.