Skip to content

Commit

Permalink
scrolling qml waveformdisplay working
Browse files Browse the repository at this point in the history
  • Loading branch information
m0dB authored and acolombier committed Oct 22, 2024
1 parent f8033d0 commit 32b7991
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 30 deletions.
7 changes: 7 additions & 0 deletions res/qml/Mixxx/Controls/WaveformDisplay.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Mixxx 1.0 as Mixxx

Mixxx.WaveformDisplay {
id: root

player: Mixxx.PlayerManager.getPlayer(root.group)
}
31 changes: 29 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <QtDebug>
#include <QtGlobal>
#include <cstdio>
#include <memory>
#include <stdexcept>

#include "config.h"
Expand All @@ -16,7 +17,11 @@
#include "errordialoghandler.h"
#include "mixxxapplication.h"
#ifdef MIXXX_USE_QML
#include "mixer/playermanager.h"
#include "qml/qmlapplication.h"
#include "waveform/guitick.h"
#include "waveform/visualsmanager.h"
#include "waveform/waveformwidgetfactory.h"
#endif
#include "mixxxmainwindow.h"
#if defined(__WINDOWS__)
Expand Down Expand Up @@ -57,8 +62,30 @@ int runMixxx(MixxxApplication* pApp, const CmdlineArgs& args) {
int exitCode;
#ifdef MIXXX_USE_QML
if (args.isQml()) {
mixxx::qml::QmlApplication qmlApplication(pApp, pCoreServices);
exitCode = pApp->exec();
auto pTick = std::make_unique<GuiTick>();
auto pVisuals = std::make_unique<VisualsManager>();
WaveformWidgetFactory::createInstance(); // takes a long time
WaveformWidgetFactory::instance()->setConfig(pCoreServices->getSettings());
WaveformWidgetFactory::instance()->startVSync(pTick.get(), pVisuals.get());
{
mixxx::qml::QmlApplication qmlApplication(pApp, pCoreServices);
const QStringList visualGroups =
pCoreServices->getPlayerManager()->getVisualPlayerGroups();
for (const QString& group : visualGroups) {
pVisuals->addDeck(group);
}
pCoreServices->getPlayerManager()->connect(pCoreServices->getPlayerManager().get(),
&PlayerManager::numberOfDecksChanged,
&qmlApplication,
[&pVisuals](int decks) {
for (int i = 0; i < decks; ++i) {
QString group = PlayerManager::groupForDeck(i);
pVisuals->addDeckIfNotExist(group);
}
});
exitCode = pApp->exec();
}
WaveformWidgetFactory::destroy();
} else
#endif
{
Expand Down
2 changes: 1 addition & 1 deletion src/qml/qmlplayermanagerproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ QmlPlayerManagerProxy::QmlPlayerManagerProxy(
: QObject(parent), m_pPlayerManager(pPlayerManager) {
}

QObject* QmlPlayerManagerProxy::getPlayer(const QString& group) {
QmlPlayerProxy* QmlPlayerManagerProxy::getPlayer(const QString& group) {
BaseTrackPlayer* pPlayer = m_pPlayerManager->getPlayer(group);
if (!pPlayer) {
qWarning() << "PlayerManagerProxy failed to find player for group" << group;
Expand Down
2 changes: 1 addition & 1 deletion src/qml/qmlplayermanagerproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class QmlPlayerManagerProxy : public QObject {
std::shared_ptr<PlayerManager> pPlayerManager,
QObject* parent = nullptr);

Q_INVOKABLE QObject* getPlayer(const QString& deck);
Q_INVOKABLE QmlPlayerProxy* getPlayer(const QString& deck);
Q_INVOKABLE void loadLocationIntoNextAvailableDeck(const QString& location, bool play = false);
Q_INVOKABLE void loadLocationUrlIntoNextAvailableDeck(
const QUrl& locationUrl, bool play = false);
Expand Down
9 changes: 9 additions & 0 deletions src/waveform/isynctimeprovider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "util/performancetimer.h"

class ISyncTimeProvider {
public:
virtual int fromTimerToNextSyncMicros(const PerformanceTimer& timer) = 0;
virtual int getSyncIntervalTimeMicros() const = 0;
};
27 changes: 9 additions & 18 deletions src/waveform/visualplayposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "moc_visualplayposition.cpp"
#include "util/cmdlineargs.h"
#include "util/math.h"
#include "waveform/vsyncthread.h"
#include "waveform/isynctimeprovider.h"

//static
QMap<QString, QWeakPointer<VisualPlayPosition>> VisualPlayPosition::m_listVisualPlayPosition;
Expand Down Expand Up @@ -57,20 +57,10 @@ void VisualPlayPosition::set(
}

double VisualPlayPosition::calcOffsetAtNextVSync(
VSyncThread* pVSyncThread, const VisualPlayPositionData& data) {
ISyncTimeProvider* pSyncTimeProvider, const VisualPlayPositionData& data) {
if (data.m_audioBufferMicroS != 0.0) {
int refToVSync;
int syncIntervalTimeMicros;
#ifdef MIXXX_USE_QML
if (CmdlineArgs::Instance().isQml()) {
refToVSync = 0;
syncIntervalTimeMicros = 0;
} else
#endif
{
refToVSync = pVSyncThread->fromTimerToNextSyncMicros(data.m_referenceTime);
syncIntervalTimeMicros = pVSyncThread->getSyncIntervalTimeMicros();
}
int refToVSync = pSyncTimeProvider->fromTimerToNextSyncMicros(data.m_referenceTime);
int syncIntervalTimeMicros = pSyncTimeProvider->getSyncIntervalTimeMicros();
// The positive offset is limited to the audio buffer + 2 x waveform sync interval
// This should be sufficient to compensate jitter, but does not continue
// in case of underflows.
Expand Down Expand Up @@ -161,22 +151,23 @@ double VisualPlayPosition::determinePlayPosInLoopBoundries(
return interpolatedPlayPos;
}

double VisualPlayPosition::getAtNextVSync(VSyncThread* pVSyncThread) {
double VisualPlayPosition::getAtNextVSync(ISyncTimeProvider* pSyncTimeProvider) {
if (m_valid) {
const VisualPlayPositionData data = m_data.getValue();
const double offset = calcOffsetAtNextVSync(pVSyncThread, data);
const double offset = calcOffsetAtNextVSync(pSyncTimeProvider, data);

return determinePlayPosInLoopBoundries(data, offset);
}
return -1;
}

void VisualPlayPosition::getPlaySlipAtNextVSync(VSyncThread* pVSyncThread,
void VisualPlayPosition::getPlaySlipAtNextVSync(
ISyncTimeProvider* pSyncTimeProvider,
double* pPlayPosition,
double* pSlipPosition) {
if (m_valid) {
const VisualPlayPositionData data = m_data.getValue();
const double offset = calcOffsetAtNextVSync(pVSyncThread, data);
const double offset = calcOffsetAtNextVSync(pSyncTimeProvider, data);

double interpolatedPlayPos = determinePlayPosInLoopBoundries(data, offset);
*pPlayPosition = interpolatedPlayPos;
Expand Down
9 changes: 5 additions & 4 deletions src/waveform/visualplayposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "util/performancetimer.h"

class ControlProxy;
class VSyncThread;
class ISyncTimeProvider;

// This class is for synchronizing the sound device DAC time with the waveforms, displayed on the
// graphic device, using the CPU time
Expand Down Expand Up @@ -67,8 +67,8 @@ class VisualPlayPosition : public QObject {
double tempoTrackSeconds,
double audioBufferMicroS);

double getAtNextVSync(VSyncThread* pVSyncThread);
void getPlaySlipAtNextVSync(VSyncThread* pVSyncThread,
double getAtNextVSync(ISyncTimeProvider* pSyncTimeProvider);
void getPlaySlipAtNextVSync(ISyncTimeProvider* pSyncTimeProvider,
double* playPosition,
double* slipPosition);
double determinePlayPosInLoopBoundries(
Expand All @@ -89,7 +89,8 @@ class VisualPlayPosition : public QObject {
}

private:
double calcOffsetAtNextVSync(VSyncThread* pVSyncThread, const VisualPlayPositionData& data);
double calcOffsetAtNextVSync(ISyncTimeProvider* pSyncTimeProvider,
const VisualPlayPositionData& data);
ControlValueAtomic<VisualPlayPositionData> m_data;
bool m_valid;
QString m_key;
Expand Down
11 changes: 7 additions & 4 deletions src/waveform/vsyncthread.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
#include <mutex>

#include "util/performancetimer.h"
#include "waveform/isynctimeprovider.h"

class WGLWidget;

class VSyncThread : public QThread {
class VSyncThread : public QThread, public ISyncTimeProvider {
Q_OBJECT
public:
enum VSyncMode {
Expand All @@ -26,20 +27,22 @@ class VSyncThread : public QThread {
VSyncThread(QObject* pParent, VSyncMode vSyncMode);
~VSyncThread();

void run();
void run() override;

bool waitForVideoSync(WGLWidget* glw);
int elapsed();
void setSyncIntervalTimeMicros(int usSyncTimer);
int droppedFrames();
void setSwapWait(int sw);
int fromTimerToNextSyncMicros(const PerformanceTimer& timer);
// ISyncTimerProvider
int fromTimerToNextSyncMicros(const PerformanceTimer& timer) override;
void vsyncSlotFinished();
void getAvailableVSyncTypes(QList<QPair<int, QString>>* list);
void setupSync(WGLWidget* glw, int index);
void waitUntilSwap(WGLWidget* glw);
mixxx::Duration sinceLastSwap() const;
int getSyncIntervalTimeMicros() const {
// ISyncTimerProvider
int getSyncIntervalTimeMicros() const override {
return m_syncIntervalTimeMicros;
}
void updatePLL();
Expand Down

0 comments on commit 32b7991

Please sign in to comment.