Merge lp:~mixxxdevelopers/mixxx/waveform-dejerk into lp:~mixxxdevelopers/mixxx/trunk

Proposed by Daniel Schürmann
Status: Needs review
Proposed branch: lp:~mixxxdevelopers/mixxx/waveform-dejerk
Merge into: lp:~mixxxdevelopers/mixxx/trunk
Diff against target: 3371 lines (+1344/-530)
50 files modified
mixxx/build/depends.py (+4/-0)
mixxx/src/controlobjectbase.h (+147/-0)
mixxx/src/dlgprefcontrols.cpp (+16/-23)
mixxx/src/dlgprefcontrols.h (+1/-6)
mixxx/src/engine/bpmcontrol.cpp (+3/-2)
mixxx/src/engine/enginebuffer.cpp (+9/-10)
mixxx/src/engine/enginebuffer.h (+3/-2)
mixxx/src/main.cpp (+9/-0)
mixxx/src/mixxx.cpp (+1/-3)
mixxx/src/sounddeviceportaudio.cpp (+2/-0)
mixxx/src/visualplayposition.cpp (+109/-0)
mixxx/src/visualplayposition.h (+57/-0)
mixxx/src/waveform/renderers/glvsynctestrenderer.cpp (+133/-0)
mixxx/src/waveform/renderers/glvsynctestrenderer.h (+19/-0)
mixxx/src/waveform/renderers/waveformrenderbeat.cpp (+1/-1)
mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp (+16/-2)
mixxx/src/waveform/renderers/waveformrendererendoftrack.h (+2/-1)
mixxx/src/waveform/renderers/waveformrendererhsv.cpp (+0/-177)
mixxx/src/waveform/renderers/waveformrendererhsv.h (+0/-21)
mixxx/src/waveform/renderers/waveformrendererpreroll.cpp (+5/-3)
mixxx/src/waveform/renderers/waveformrendermark.cpp (+2/-2)
mixxx/src/waveform/renderers/waveformrendermarkrange.cpp (+2/-2)
mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp (+50/-50)
mixxx/src/waveform/renderers/waveformwidgetrenderer.h (+7/-4)
mixxx/src/waveform/vsyncthread.cpp (+179/-0)
mixxx/src/waveform/vsyncthread.h (+109/-0)
mixxx/src/waveform/waveformwidgetfactory.cpp (+160/-55)
mixxx/src/waveform/waveformwidgetfactory.h (+27/-16)
mixxx/src/waveform/widgets/emptywaveformwidget.cpp (+6/-0)
mixxx/src/waveform/widgets/emptywaveformwidget.h (+2/-1)
mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp (+19/-4)
mixxx/src/waveform/widgets/glsimplewaveformwidget.h (+6/-5)
mixxx/src/waveform/widgets/glslwaveformwidget.cpp (+23/-3)
mixxx/src/waveform/widgets/glslwaveformwidget.h (+7/-5)
mixxx/src/waveform/widgets/glvsynctestwidget.cpp (+75/-0)
mixxx/src/waveform/widgets/glvsynctestwidget.h (+30/-0)
mixxx/src/waveform/widgets/glwaveformwidget.cpp (+18/-4)
mixxx/src/waveform/widgets/glwaveformwidget.h (+5/-4)
mixxx/src/waveform/widgets/hsvwaveformwidget.cpp (+0/-41)
mixxx/src/waveform/widgets/hsvwaveformwidget.h (+0/-29)
mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp (+19/-4)
mixxx/src/waveform/widgets/qtsimplewaveformwidget.h (+6/-5)
mixxx/src/waveform/widgets/qtwaveformwidget.cpp (+19/-4)
mixxx/src/waveform/widgets/qtwaveformwidget.h (+6/-5)
mixxx/src/waveform/widgets/softwarewaveformwidget.h (+5/-5)
mixxx/src/waveform/widgets/waveformwidgetabstract.cpp (+8/-15)
mixxx/src/waveform/widgets/waveformwidgetabstract.h (+5/-4)
mixxx/src/waveform/widgets/waveformwidgettype.h (+3/-2)
mixxx/src/widget/wspinny.cpp (+7/-8)
mixxx/src/widget/wspinny.h (+2/-2)
To merge this branch: bzr merge lp:~mixxxdevelopers/mixxx/waveform-dejerk
Reviewer Review Type Date Requested Status
Mixxx Development Team Pending
Review via email: mp+156977@code.launchpad.net

Description of the change

This branch contains the first transition of waveform dejerking.
It introduces a timestamped visual play position, a vsync thread for precise timing and the infrastructure to allow advanced vsync strategies.
In this merge, is only the simple pure timer sync strategy included for not making this merge too big.
The improvement is notable but the waveforms are still jerking.
A vsync test waveform type is included an is available by starting Mixxx with --developer.

--

The Implementation tries to display the right waveform picture in the right moment.
This is archived by the VisualPlayPosition Class. It is something like a time stamped Control object, using he new atomic ControlObjectBase for bypassing the delays from the Qt Mesasage Queue and the Sync Thread from the current Control Object implementation.

This way we get rid of unpredictable delays and mixed up message order during heavy load.

The time stamp ov the Visual Play position is generated by the Portaudio timeInfo VisualPlayPosition::setTimeInfo(timeInfo);
The Play position for the waveform is adjusted for the actual display time in
VisualPlayPosition::getAt

The display frame timing is done by a separate Thread. This is required because the Qt Timer event is not super precise. This thread controls the rendering process by using sleep() and semaphores.

Currently it is not using Time stamp information from the driver. I have relay good results with specific set-ups, but it is also suffering from driver quality in other set-ups. So I have removed this from the current merge request but I am planning to add additional advanced dejerking strategies using openGL from daschuers_trunk later.

To post a comment you must log in.
Revision history for this message
jus (jus) wrote :

FYI branch needs the diff from https://bazaar.launchpad.net/~mixxxdevelopers/mixxx/release-1.11.x/revision/3836 in order to compile on OSX. Going to test branch on MacBookPro8,1 and iMac13,1

3344. By Daniel Schürmann

merged from lp:mixxx

Revision history for this message
Daniel Schürmann (daschuer) wrote :

Thank you, for testing!

Just merged with lp:mixxx, so it should now build with OSX.

Do you have any results?

Unmerged revisions

3344. By Daniel Schürmann

merged from lp:mixxx

3343. By Daniel Schürmann

merged from lp:mixxx

3342. By Daniel Schürmann

clean up finished

3341. By Daniel Schürmann

code clean up

3340. By Daniel Schürmann

merged from lp:mixxx

3339. By Daniel Schürmann

fixed crash

3338. By Daniel Schürmann

compilable but crashing

3337. By Daniel Schürmann

merged ../daschuers_trunk/mixxx/src/waveform/

3336. By Daniel Schürmann

merged from lp:mixxx

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'mixxx/build/depends.py'
--- mixxx/build/depends.py 2013-02-09 00:49:59 +0000
+++ mixxx/build/depends.py 2013-05-01 22:08:27 +0000
@@ -632,6 +632,7 @@
632 "waveform/waveform.cpp",632 "waveform/waveform.cpp",
633 "waveform/waveformfactory.cpp",633 "waveform/waveformfactory.cpp",
634 "waveform/waveformwidgetfactory.cpp",634 "waveform/waveformwidgetfactory.cpp",
635 "waveform/vsyncthread.cpp",
635 "waveform/renderers/waveformwidgetrenderer.cpp",636 "waveform/renderers/waveformwidgetrenderer.cpp",
636 "waveform/renderers/waveformrendererabstract.cpp",637 "waveform/renderers/waveformrendererabstract.cpp",
637 "waveform/renderers/waveformrenderbackground.cpp",638 "waveform/renderers/waveformrenderbackground.cpp",
@@ -648,6 +649,7 @@
648 "waveform/renderers/glwaveformrendererfilteredsignal.cpp",649 "waveform/renderers/glwaveformrendererfilteredsignal.cpp",
649 "waveform/renderers/glwaveformrenderersimplesignal.cpp",650 "waveform/renderers/glwaveformrenderersimplesignal.cpp",
650 "waveform/renderers/glslwaveformrenderersignal.cpp",651 "waveform/renderers/glslwaveformrenderersignal.cpp",
652 "waveform/renderers/glvsynctestrenderer.cpp",
651653
652 "waveform/renderers/waveformsignalcolors.cpp",654 "waveform/renderers/waveformsignalcolors.cpp",
653655
@@ -664,6 +666,7 @@
664 "waveform/widgets/qtsimplewaveformwidget.cpp",666 "waveform/widgets/qtsimplewaveformwidget.cpp",
665 "waveform/widgets/glwaveformwidget.cpp",667 "waveform/widgets/glwaveformwidget.cpp",
666 "waveform/widgets/glsimplewaveformwidget.cpp",668 "waveform/widgets/glsimplewaveformwidget.cpp",
669 "waveform/widgets/glvsynctestwidget.cpp",
667670
668 "waveform/widgets/glslwaveformwidget.cpp",671 "waveform/widgets/glslwaveformwidget.cpp",
669672
@@ -696,6 +699,7 @@
696 "soundmanagerutil.cpp",699 "soundmanagerutil.cpp",
697 "dlgprefrecord.cpp",700 "dlgprefrecord.cpp",
698 "playerinfo.cpp",701 "playerinfo.cpp",
702 "visualplayposition.cpp",
699703
700 "recording/enginerecord.cpp",704 "recording/enginerecord.cpp",
701 "recording/encoder.cpp",705 "recording/encoder.cpp",
702706
=== added file 'mixxx/src/controlobjectbase.h'
--- mixxx/src/controlobjectbase.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/controlobjectbase.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,147 @@
1
2#ifndef CONTROLOBJECTBASE_H_
3#define CONTROLOBJECTBASE_H_
4
5#include <QAtomicInt>
6#include <QObject>
7
8static const int cReaderSlotCnt = 7;
9
10template<typename T>
11class ControlObjectRingValue {
12 public:
13 ControlObjectRingValue()
14 : m_value(T()),
15 m_readerSlots(cReaderSlotCnt) {
16 }
17
18 int tryGet(T* value) {
19 // Read while consuming one readerSlot
20 bool originalSlots = m_readerSlots.fetchAndAddAcquire(-1);
21 if (originalSlots) {
22 *value = m_value;
23 }
24 (void)m_readerSlots.fetchAndAddRelease(1);
25 return originalSlots;
26 }
27
28 bool trySet(const T& value) {
29 // try to lock this element entirely for reading
30 if (m_readerSlots.testAndSetAcquire(cReaderSlotCnt, 0)) {
31 m_value = value;
32 m_readerSlots.fetchAndAddRelease(cReaderSlotCnt);
33 return true;
34 }
35 return false;
36 }
37
38 private:
39 T m_value;
40 QAtomicInt m_readerSlots;
41};
42
43// Common implementation for all Types
44template<typename T, bool ATOMIC = false>
45class ControlObjectValue {
46 public:
47 inline T getValue() {
48 T value = T();
49 unsigned int index = (unsigned int)m_readIndex
50 % (cReaderSlotCnt + 1);
51 while (m_ring[index].tryGet(&value) == 0) {
52 // We are here if
53 // 1) there are more then cReaderSlotCnt reader (get) reading the same value or
54 // 2) the formerly current value is locked by a writer
55 // Case 1 is prevented by enough reader slots and schould not happen
56 // Case 2 happens when the a reader is delayed after reading the
57 // m_currentIndex and the writers have written cReaderSlotCnt times so that the
58 // formally current value is locked again for writing.
59 // In both cases reading the less recent value will fix it.
60 index = (index - 1) % (cReaderSlotCnt + 1);
61 }
62 return value;
63 }
64
65 inline void setValue(const T& value) {
66 // Test if we can read atomic
67 // This test is const and will be mad only at compile time
68 unsigned int index;
69 do {
70 index = (unsigned int)m_writeIndex.fetchAndAddAcquire(1)
71 % (cReaderSlotCnt + 1);
72 // This will be repeated if the value is locked
73 // 1) by an other writer writing at the same time or
74 // 2) a delayed reader is still blocking the formerly current value
75 // In both cases writing to the next value will fix it.
76 } while (!m_ring[index].trySet(value));
77 m_readIndex = (int)index;
78 }
79
80 protected:
81 ControlObjectValue()
82 : m_readIndex(0),
83 m_writeIndex(1) {
84 }
85
86 private:
87 ControlObjectRingValue<T> m_ring[cReaderSlotCnt+1];
88 QAtomicInt m_readIndex;
89 QAtomicInt m_writeIndex;
90};
91
92// Specialized Template for atomic types
93template<typename T>
94class ControlObjectValue<T, true> {
95 public:
96 inline T getValue() {
97 return m_value;
98 }
99
100 inline void setValue(const T& value) {
101 m_value = value;
102 }
103
104 protected:
105 ControlObjectValue()
106 : m_value(T()) {
107 }
108
109 private:
110 T m_value;
111};
112
113// Note: Qt does not support templates for signal and slots
114// So the typified ControlObject has to handle the Event Queue connections
115template<typename T>
116class ControlObjectBase
117 : public ControlObjectValue<T, sizeof(T) <= sizeof(void*)> {
118 public:
119 ControlObjectBase()
120 : ControlObjectValue<T, sizeof(T) <= sizeof(void*)>() {
121 }
122};
123
124
125template<typename T>
126class ControlObjectThreadBase {
127 public:
128 ControlObjectThreadBase(ControlObjectBase<T>* pControlObject)
129 : m_pControlObject(pControlObject) {
130 }
131 virtual ~ControlObjectThreadBase();
132
133 inline T get() const {
134 return m_pControlObject->get();
135 }
136
137 inline void set(const T& value) {
138 return m_pControlObject->get();
139 }
140
141 private:
142 ControlObjectBase<T>* m_pControlObject;
143};
144
145
146#endif // CONTROLOBJECTBASE_H_
147
0148
=== modified file 'mixxx/src/dlgprefcontrols.cpp'
--- mixxx/src/dlgprefcontrols.cpp 2013-01-27 23:04:37 +0000
+++ mixxx/src/dlgprefcontrols.cpp 2013-05-01 22:08:27 +0000
@@ -44,7 +44,6 @@
44 ConfigObject<ConfigValue> * pConfig)44 ConfigObject<ConfigValue> * pConfig)
45 : QWidget(parent) {45 : QWidget(parent) {
46 m_pConfig = pConfig;46 m_pConfig = pConfig;
47 m_timer = -1;
48 m_mixxx = mixxx;47 m_mixxx = mixxx;
49 m_pSkinLoader = pSkinLoader;48 m_pSkinLoader = pSkinLoader;
50 m_pPlayerManager = pPlayerManager;49 m_pPlayerManager = pPlayerManager;
@@ -597,24 +596,14 @@
597 WaveformWidgetFactory::instance()->setOverviewNormalized(normalize);596 WaveformWidgetFactory::instance()->setOverviewNormalized(normalize);
598}597}
599598
600void DlgPrefControls::onShow() {599void DlgPrefControls::slotWaveformMeasured(float frameRate, int rtErrorCnt) {
601 m_timer = startTimer(100); //refresh actual frame rate every 100 ms600 frameRateAverage->setText(
602}601 QString::number((double)frameRate, 'f', 2) +
603602 " e" +
604void DlgPrefControls::onHide() {603 QString::number(rtErrorCnt));
605 if (m_timer != -1) {604}
606 killTimer(m_timer);605
607 }606void DlgPrefControls::initWaveformControl() {
608}
609
610void DlgPrefControls::timerEvent(QTimerEvent * /*event*/) {
611 //Just to refresh actual framrate any time the controller is modified
612 frameRateAverage->setText(QString::number(
613 WaveformWidgetFactory::instance()->getActualFrameRate()));
614}
615
616void DlgPrefControls::initWaveformControl()
617{
618 waveformTypeComboBox->clear();607 waveformTypeComboBox->clear();
619 WaveformWidgetFactory* factory = WaveformWidgetFactory::instance();608 WaveformWidgetFactory* factory = WaveformWidgetFactory::instance();
620609
@@ -626,15 +615,17 @@
626 WaveformWidgetType::Type currentType = factory->getType();615 WaveformWidgetType::Type currentType = factory->getType();
627 int currentIndex = -1;616 int currentIndex = -1;
628617
629 std::vector<WaveformWidgetAbstractHandle> handles = factory->getAvailableTypes();618 QVector<WaveformWidgetAbstractHandle> handles = factory->getAvailableTypes();
630 for (unsigned int i = 0; i < handles.size(); i++) {619 for (int i = 0; i < handles.size(); i++) {
631 waveformTypeComboBox->addItem(handles[i].getDisplayName());620 waveformTypeComboBox->addItem(handles[i].getDisplayName());
632 if (handles[i].getType() == currentType)621 if (handles[i].getType() == currentType) {
633 currentIndex = i;622 currentIndex = i;
623 }
634 }624 }
635625
636 if (currentIndex != -1)626 if (currentIndex != -1) {
637 waveformTypeComboBox->setCurrentIndex(currentIndex);627 waveformTypeComboBox->setCurrentIndex(currentIndex);
628 }
638629
639 frameRateSpinBox->setValue(factory->getFrameRate());630 frameRateSpinBox->setValue(factory->getFrameRate());
640631
@@ -671,6 +662,8 @@
671 connect(normalizeOverviewCheckBox,SIGNAL(toggled(bool)),662 connect(normalizeOverviewCheckBox,SIGNAL(toggled(bool)),
672 this,SLOT(slotSetNormalizeOverview(bool)));663 this,SLOT(slotSetNormalizeOverview(bool)));
673664
665 connect(WaveformWidgetFactory::instance(), SIGNAL(waveformMeasured(float,int)),
666 this, SLOT(slotWaveformMeasured(float,int)));
674}667}
675668
676//Returns TRUE if skin fits to screen resolution, FALSE otherwise669//Returns TRUE if skin fits to screen resolution, FALSE otherwise
677670
=== modified file 'mixxx/src/dlgprefcontrols.h'
--- mixxx/src/dlgprefcontrols.h 2013-01-27 23:04:37 +0000
+++ mixxx/src/dlgprefcontrols.h 2013-05-01 22:08:27 +0000
@@ -73,12 +73,7 @@
73 void slotSetVisualGainMid(double gain);73 void slotSetVisualGainMid(double gain);
74 void slotSetVisualGainHigh(double gain);74 void slotSetVisualGainHigh(double gain);
75 void slotSetNormalizeOverview( bool normalize);75 void slotSetNormalizeOverview( bool normalize);
7676 void slotWaveformMeasured(float frameRate, int rtErrorCnt);
77 virtual void onShow();
78 virtual void onHide();
79
80protected:
81 void timerEvent(QTimerEvent *);
8277
83private:78private:
84 void initWaveformControl();79 void initWaveformControl();
8580
=== modified file 'mixxx/src/engine/bpmcontrol.cpp'
--- mixxx/src/engine/bpmcontrol.cpp 2013-03-31 16:56:35 +0000
+++ mixxx/src/engine/bpmcontrol.cpp 2013-05-01 22:08:27 +0000
@@ -8,6 +8,7 @@
88
9#include "engine/enginebuffer.h"9#include "engine/enginebuffer.h"
10#include "engine/bpmcontrol.h"10#include "engine/bpmcontrol.h"
11#include "visualplayposition.h"
11#include "engine/enginechannel.h"12#include "engine/enginechannel.h"
12#include "engine/enginemaster.h"13#include "engine/enginemaster.h"
1314
@@ -318,8 +319,8 @@
318 double dThisPosition = getCurrentSample();319 double dThisPosition = getCurrentSample();
319 double dOtherLength = ControlObject::getControl(320 double dOtherLength = ControlObject::getControl(
320 ConfigKey(pOtherEngineBuffer->getGroup(), "track_samples"))->get();321 ConfigKey(pOtherEngineBuffer->getGroup(), "track_samples"))->get();
321 double dOtherEnginePlayPos = ControlObject::getControl(322 double dOtherEnginePlayPos =
322 ConfigKey(pOtherEngineBuffer->getGroup(), "visual_playposition"))->get();323 VisualPlayPosition::getVisualPlayPosition(pOtherEngineBuffer->getGroup())->getEnginePlayPos();
323 double dOtherPosition = dOtherLength * dOtherEnginePlayPos;324 double dOtherPosition = dOtherLength * dOtherEnginePlayPos;
324325
325 double dThisPrevBeat = m_pBeats->findPrevBeat(dThisPosition);326 double dThisPrevBeat = m_pBeats->findPrevBeat(dThisPosition);
326327
=== modified file 'mixxx/src/engine/enginebuffer.cpp'
--- mixxx/src/engine/enginebuffer.cpp 2013-04-23 18:15:21 +0000
+++ mixxx/src/engine/enginebuffer.cpp 2013-05-01 22:08:27 +0000
@@ -37,6 +37,7 @@
37#include "engine/ratecontrol.h"37#include "engine/ratecontrol.h"
38#include "engine/bpmcontrol.h"38#include "engine/bpmcontrol.h"
39#include "engine/quantizecontrol.h"39#include "engine/quantizecontrol.h"
40#include "visualplayposition.h"
40#include "util/timer.h"41#include "util/timer.h"
4142
42#ifdef __VINYLCONTROL__43#ifdef __VINYLCONTROL__
@@ -148,7 +149,6 @@
148 connect(m_pSlipButton, SIGNAL(valueChangedFromEngine(double)),149 connect(m_pSlipButton, SIGNAL(valueChangedFromEngine(double)),
149 this, SLOT(slotControlSlip(double)),150 this, SLOT(slotControlSlip(double)),
150 Qt::DirectConnection);151 Qt::DirectConnection);
151 m_pSlipPosition = new ControlObject(ConfigKey(m_group, "slip_playposition"));
152152
153 // Actual rate (used in visuals, not for control)153 // Actual rate (used in visuals, not for control)
154 m_rateEngine = new ControlObject(ConfigKey(m_group, "rateEngine"));154 m_rateEngine = new ControlObject(ConfigKey(m_group, "rateEngine"));
@@ -165,8 +165,7 @@
165 Qt::DirectConnection);165 Qt::DirectConnection);
166166
167 // Control used to communicate ratio playpos to GUI thread167 // Control used to communicate ratio playpos to GUI thread
168 m_visualPlaypos = new ControlPotmeter(168 m_visualPlayPos = VisualPlayPosition::getVisualPlayPosition(m_group);
169 ConfigKey(m_group, "visual_playposition"), kMinPlayposRange, kMaxPlayposRange);
170169
171 m_pRepeat = new ControlPushButton(ConfigKey(m_group, "repeat"));170 m_pRepeat = new ControlPushButton(ConfigKey(m_group, "repeat"));
172 m_pRepeat->setButtonMode(ControlPushButton::TOGGLE);171 m_pRepeat->setButtonMode(ControlPushButton::TOGGLE);
@@ -251,11 +250,9 @@
251 delete m_stopButton;250 delete m_stopButton;
252 delete m_rateEngine;251 delete m_rateEngine;
253 delete m_playposSlider;252 delete m_playposSlider;
254 delete m_visualPlaypos;
255 delete m_visualBpm;253 delete m_visualBpm;
256254
257 delete m_pSlipButton;255 delete m_pSlipButton;
258 delete m_pSlipPosition;
259 delete m_pRepeat;256 delete m_pRepeat;
260257
261 delete m_pTrackSamples;258 delete m_pTrackSamples;
@@ -384,7 +381,7 @@
384 int iTrackSampleRate,381 int iTrackSampleRate,
385 int iTrackNumSamples) {382 int iTrackNumSamples) {
386 m_pause.lock();383 m_pause.lock();
387 m_visualPlaypos->set(-1);384 m_visualPlayPos->setInvalid();
388 m_pCurrentTrack = pTrack;385 m_pCurrentTrack = pTrack;
389 m_file_srate_old = iTrackSampleRate;386 m_file_srate_old = iTrackSampleRate;
390 m_file_length_old = iTrackNumSamples;387 m_file_length_old = iTrackNumSamples;
@@ -527,13 +524,11 @@
527 // TODO(rryan): Should this filepos instead be the RAMAN current524 // TODO(rryan): Should this filepos instead be the RAMAN current
528 // position? filepos_play could be out of date.525 // position? filepos_play could be out of date.
529 m_dSlipPosition = m_filepos_play;526 m_dSlipPosition = m_filepos_play;
530 m_pSlipPosition->set(fractionalPlayposFromAbsolute(m_dSlipPosition));
531 m_dSlipRate = m_rate_old;527 m_dSlipRate = m_rate_old;
532 } else {528 } else {
533 // TODO(owen) assuming that looping will get canceled properly529 // TODO(owen) assuming that looping will get canceled properly
534 slotControlSeekAbs(m_dSlipPosition);530 slotControlSeekAbs(m_dSlipPosition);
535 m_dSlipPosition = 0;531 m_dSlipPosition = 0;
536 m_pSlipPosition->set(0);
537 }532 }
538}533}
539534
@@ -577,7 +572,6 @@
577 // Update the slipped position572 // Update the slipped position
578 if (m_bSlipEnabled) {573 if (m_bSlipEnabled) {
579 m_dSlipPosition += static_cast<double>(iBufferSize) * m_dSlipRate;574 m_dSlipPosition += static_cast<double>(iBufferSize) * m_dSlipRate;
580 m_pSlipPosition->set(fractionalPlayposFromAbsolute(m_dSlipPosition));
581 }575 }
582576
583 // Scratching always disables keylock because keylock sounds terrible577 // Scratching always disables keylock because keylock sounds terrible
@@ -852,6 +846,9 @@
852 m_iSamplesCalculated += iBufferSize;846 m_iSamplesCalculated += iBufferSize;
853847
854 double fFractionalPlaypos = fractionalPlayposFromAbsolute(m_filepos_play);848 double fFractionalPlaypos = fractionalPlayposFromAbsolute(m_filepos_play);
849 if(rate > 0 && fFractionalPlaypos == 1.0) {
850 rate = 0;
851 }
855852
856 // Update indicators that are only updated after every853 // Update indicators that are only updated after every
857 // sampleRate/kiUpdateRate samples processed. (e.g. playposSlider,854 // sampleRate/kiUpdateRate samples processed. (e.g. playposSlider,
@@ -874,7 +871,9 @@
874871
875 // Update visual control object, this needs to be done more often than the872 // Update visual control object, this needs to be done more often than the
876 // rateEngine and playpos slider873 // rateEngine and playpos slider
877 m_visualPlaypos->set(fFractionalPlaypos);874 m_visualPlayPos->set(fFractionalPlaypos, rate,
875 (double)iBufferSize/m_file_length_old,
876 fractionalPlayposFromAbsolute(m_dSlipPosition));
878}877}
879878
880void EngineBuffer::hintReader(const double dRate) {879void EngineBuffer::hintReader(const double dRate) {
881880
=== modified file 'mixxx/src/engine/enginebuffer.h'
--- mixxx/src/engine/enginebuffer.h 2013-02-03 18:50:24 +0000
+++ mixxx/src/engine/enginebuffer.h 2013-05-01 22:08:27 +0000
@@ -49,6 +49,7 @@
49class EngineBufferScaleLinear;49class EngineBufferScaleLinear;
50class EngineBufferScaleST;50class EngineBufferScaleST;
51class EngineWorkerScheduler;51class EngineWorkerScheduler;
52class VisualPlayPosition;
52class EngineMaster;53class EngineMaster;
5354
54struct Hint;55struct Hint;
@@ -225,13 +226,11 @@
225 ControlObject* m_fwdButton;226 ControlObject* m_fwdButton;
226 ControlObject* m_backButton;227 ControlObject* m_backButton;
227 ControlPushButton* m_pSlipButton;228 ControlPushButton* m_pSlipButton;
228 ControlObject* m_pSlipPosition;
229229
230 ControlObject* m_rateEngine;230 ControlObject* m_rateEngine;
231 ControlObject* m_visualBpm;231 ControlObject* m_visualBpm;
232 ControlObject* m_pMasterRate;232 ControlObject* m_pMasterRate;
233 ControlPotmeter* m_playposSlider;233 ControlPotmeter* m_playposSlider;
234 ControlPotmeter* m_visualPlaypos;
235 ControlObject* m_pSampleRate;234 ControlObject* m_pSampleRate;
236 ControlPushButton* m_pKeylock;235 ControlPushButton* m_pKeylock;
237236
@@ -277,6 +276,8 @@
277 CSAMPLE* m_pCrossFadeBuffer;276 CSAMPLE* m_pCrossFadeBuffer;
278 int m_iCrossFadeSamples;277 int m_iCrossFadeSamples;
279 int m_iLastBufferSize;278 int m_iLastBufferSize;
279
280 VisualPlayPosition* m_visualPlayPos;
280};281};
281282
282#endif283#endif
283284
=== modified file 'mixxx/src/main.cpp'
--- mixxx/src/main.cpp 2013-04-28 18:46:48 +0000
+++ mixxx/src/main.cpp 2013-05-01 22:08:27 +0000
@@ -40,6 +40,10 @@
40#include <ladspa/ladspaloader.h>40#include <ladspa/ladspaloader.h>
41#endif41#endif
4242
43#ifdef Q_WS_X11
44#include <X11/Xlib.h>
45#endif
46
43#ifdef __WINDOWS__47#ifdef __WINDOWS__
44#ifdef DEBUGCONSOLE48#ifdef DEBUGCONSOLE
45#include <io.h> // Debug Console49#include <io.h> // Debug Console
@@ -139,6 +143,11 @@
139143
140int main(int argc, char * argv[])144int main(int argc, char * argv[])
141{145{
146
147#ifdef Q_WS_X11
148 XInitThreads();
149#endif
150
142 // Check if an instance of Mixxx is already running151 // Check if an instance of Mixxx is already running
143 // See http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication152 // See http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication
144153
145154
=== modified file 'mixxx/src/mixxx.cpp'
--- mixxx/src/mixxx.cpp 2013-05-01 20:29:44 +0000
+++ mixxx/src/mixxx.cpp 2013-05-01 22:08:27 +0000
@@ -387,6 +387,7 @@
387 this, SLOT(slotSyncControlSystem()));387 this, SLOT(slotSyncControlSystem()));
388388
389 WaveformWidgetFactory::create();389 WaveformWidgetFactory::create();
390 WaveformWidgetFactory::instance()->startVSync(this);
390 WaveformWidgetFactory::instance()->setConfig(m_pConfig);391 WaveformWidgetFactory::instance()->setConfig(m_pConfig);
391392
392 m_pSkinLoader = new SkinLoader(m_pConfig);393 m_pSkinLoader = new SkinLoader(m_pConfig);
@@ -1609,7 +1610,6 @@
16091610
1610 m_pView->hide();1611 m_pView->hide();
16111612
1612 WaveformWidgetFactory::instance()->stop();
1613 WaveformWidgetFactory::instance()->destroyWidgets();1613 WaveformWidgetFactory::instance()->destroyWidgets();
16141614
1615 // Workaround for changing skins while fullscreen, just go out of fullscreen1615 // Workaround for changing skins while fullscreen, just go out of fullscreen
@@ -1658,8 +1658,6 @@
1658 initPosition.y() + (initSize.height() - m_pView->height()) / 2);1658 initPosition.y() + (initSize.height() - m_pView->height()) / 2);
1659 }1659 }
16601660
1661 WaveformWidgetFactory::instance()->start();
1662
1663#ifdef __APPLE__1661#ifdef __APPLE__
1664 // Original the following line fixes issue on OSX where menu bar went away1662 // Original the following line fixes issue on OSX where menu bar went away
1665 // after a skin change. It was original surrounded by #if __OSX__1663 // after a skin change. It was original surrounded by #if __OSX__
16661664
=== modified file 'mixxx/src/sounddeviceportaudio.cpp'
--- mixxx/src/sounddeviceportaudio.cpp 2013-03-21 22:29:13 +0000
+++ mixxx/src/sounddeviceportaudio.cpp 2013-05-01 22:08:27 +0000
@@ -25,6 +25,7 @@
25#include "sounddeviceportaudio.h"25#include "sounddeviceportaudio.h"
26#include "soundmanagerutil.h"26#include "soundmanagerutil.h"
27#include "controlobject.h"27#include "controlobject.h"
28#include "visualplayposition.h"
28#include "util/timer.h"29#include "util/timer.h"
2930
30SoundDevicePortAudio::SoundDevicePortAudio(ConfigObject<ConfigValue> *config, SoundManager *sm,31SoundDevicePortAudio::SoundDevicePortAudio(ConfigObject<ConfigValue> *config, SoundManager *sm,
@@ -326,6 +327,7 @@
326 m_bSetThreadPriority = true;327 m_bSetThreadPriority = true;
327 }328 }
328329
330 VisualPlayPosition::setTimeInfo(timeInfo);
329 if (!m_undeflowUpdateCount) {331 if (!m_undeflowUpdateCount) {
330 if (statusFlags & (paOutputUnderflow | paInputOverflow)) {332 if (statusFlags & (paOutputUnderflow | paInputOverflow)) {
331 if (m_pMasterUnderflowCount) {333 if (m_pMasterUnderflowCount) {
332334
=== added file 'mixxx/src/visualplayposition.cpp'
--- mixxx/src/visualplayposition.cpp 1970-01-01 00:00:00 +0000
+++ mixxx/src/visualplayposition.cpp 2013-05-01 22:08:27 +0000
@@ -0,0 +1,109 @@
1
2#include <qdebug.h>
3
4#include "visualplayposition.h"
5#include "controlobjectthreadmain.h"
6#include "controlobject.h"
7#include "waveform/waveformwidgetfactory.h"
8#include "mathstuff.h"
9#include "waveform/vsyncthread.h"
10
11
12//static
13QMap<QString, VisualPlayPosition*> VisualPlayPosition::m_listVisualPlayPosition;
14const PaStreamCallbackTimeInfo* VisualPlayPosition::m_timeInfo;
15PerformanceTimer VisualPlayPosition::m_timeInfoTime;
16
17VisualPlayPosition::VisualPlayPosition() :
18 m_valid(false) {
19
20 m_audioBufferSize = new ControlObjectThreadMain(
21 ControlObject::getControl(ConfigKey("[Master]","audio_buffer_size")));
22}
23
24VisualPlayPosition::~VisualPlayPosition() {
25
26}
27
28// This function must be called only form the engine thread (PA callback)
29void VisualPlayPosition::set(double playPos, double rate,
30 double positionStep, double pSlipPosition) {
31 VisualPlayPositionData data;
32
33 data.m_referenceTime = m_timeInfoTime;
34 // Time from reference time to Buffer at DAC in µs
35 data.m_timeDac = (m_timeInfo->outputBufferDacTime - m_timeInfo->currentTime) * 1000000;
36 data.m_playPos = playPos;
37 data.m_rate = rate;
38 data.m_positionStep = positionStep;
39 data.m_pSlipPosition = pSlipPosition;
40
41 // Atomic write
42 m_data.setValue(data);
43 m_valid = true;
44}
45
46double VisualPlayPosition::getAt(VSyncThread* vsyncThread) {
47 //static double testPos = 0;
48 //testPos += 0.000017759; //0.000016608; // 1.46257e-05;
49 //return testPos;
50
51 if (m_valid) {
52 VisualPlayPositionData data = m_data.getValue();
53 int usRefToVSync = vsyncThread->usFromTimerToNextSync(&data.m_referenceTime);
54 int offset = usRefToVSync - data.m_timeDac;
55 double playPos = data.m_playPos; // load playPos for the first sample in Buffer
56 playPos += data.m_positionStep * offset * data.m_rate / m_audioBufferSize->get() / 1000;
57 //qDebug() << "delta Pos" << playPos - m_playPosOld << offset;
58 m_playPosOld = playPos;
59 return playPos;
60 }
61 return -1;
62}
63
64void VisualPlayPosition::getPlaySlipAt(int usFromNow, double* playPosition, double* slipPosition) {
65 //static double testPos = 0;
66 //testPos += 0.000017759; //0.000016608; // 1.46257e-05;
67 //return testPos;
68
69 if (m_valid) {
70 VisualPlayPositionData data = m_data.getValue();
71 int usElapsed = data.m_referenceTime.elapsed() / 1000;
72 int dacFromNow = usElapsed - data.m_timeDac;
73 int offset = dacFromNow - usFromNow;
74 double playPos = data.m_playPos; // load playPos for the first sample in Buffer
75 playPos += data.m_positionStep * offset * data.m_rate / m_audioBufferSize->get() / 1000;
76 *playPosition = playPos;
77 *slipPosition = data.m_pSlipPosition;
78 }
79}
80
81double VisualPlayPosition::getEnginePlayPos() {
82 if (m_valid) {
83 VisualPlayPositionData data = m_data.getValue();
84 return data.m_playPos;
85 } else {
86 return -1;
87 }
88}
89
90//static
91VisualPlayPosition* VisualPlayPosition::getVisualPlayPosition(QString group) {
92 VisualPlayPosition* vpp = m_listVisualPlayPosition[group];
93 if (!vpp) {
94 vpp = new VisualPlayPosition();
95 m_listVisualPlayPosition[group] = vpp;
96 }
97 return vpp;
98}
99
100//static
101void VisualPlayPosition::setTimeInfo(const PaStreamCallbackTimeInfo *timeInfo) {
102 m_timeInfo = timeInfo;
103 m_timeInfoTime.start();
104 //qDebug() << "TimeInfo" << (timeInfo->currentTime - floor(timeInfo->currentTime)) << (timeInfo->outputBufferDacTime - floor(timeInfo->outputBufferDacTime));
105 //m_timeInfo.currentTime = timeInfo->currentTime;
106 //m_timeInfo.inputBufferAdcTime = timeInfo->inputBufferAdcTime;
107 //m_timeInfo.outputBufferDacTime = timeInfo->outputBufferDacTime;
108}
109
0110
=== added file 'mixxx/src/visualplayposition.h'
--- mixxx/src/visualplayposition.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/visualplayposition.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,57 @@
1#ifndef VISUALPLAYPOSITION_H
2#define VISUALPLAYPOSITION_H
3
4#include <portaudio.h>
5#include "util/performancetimer.h"
6#include "controlobjectbase.h"
7
8#include <QMutex>
9#include <QTime>
10#include <QMap>
11#include <QAtomicPointer>
12
13class ControlObjectThreadMain;
14class VSyncThread;
15
16class VisualPlayPositionData {
17 public:
18 PerformanceTimer m_referenceTime;
19 int m_timeDac;
20 double m_playPos;
21 double m_rate;
22 double m_positionStep;
23 double m_pSlipPosition;
24};
25
26
27class VisualPlayPosition
28{
29 public:
30 VisualPlayPosition();
31 ~VisualPlayPosition();
32
33 void set(double playPos, double rate, double positionStep, double pSlipPosition);
34 double getAt(VSyncThread* vsyncThread);
35 void getPlaySlipAt(int usFromNow, double* playPosition, double* slipPosition);
36 double getEnginePlayPos();
37 static VisualPlayPosition* getVisualPlayPosition(QString group);
38 static void setTimeInfo(const PaStreamCallbackTimeInfo *timeInfo);
39 void setInvalid() { m_valid = false; };
40
41
42 private:
43 ControlObjectBase<VisualPlayPositionData> m_data;
44 double m_playPosOld;
45 int m_deltatime;
46 ControlObjectThreadMain* m_audioBufferSize;
47 PaTime m_outputBufferDacTime;
48 bool m_valid;
49
50 static QMap<QString, VisualPlayPosition*> m_listVisualPlayPosition;
51 static const PaStreamCallbackTimeInfo* m_timeInfo;
52 static PerformanceTimer m_timeInfoTime;
53
54};
55
56#endif // VISUALPLAYPOSITION_H
57
058
=== added file 'mixxx/src/waveform/renderers/glvsynctestrenderer.cpp'
--- mixxx/src/waveform/renderers/glvsynctestrenderer.cpp 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/renderers/glvsynctestrenderer.cpp 2013-05-01 22:08:27 +0000
@@ -0,0 +1,133 @@
1#include "glvsynctestrenderer.h"
2
3#include "waveformwidgetrenderer.h"
4#include "waveform/waveform.h"
5
6#include "waveform/waveformwidgetfactory.h"
7
8#include "util/performancetimer.h"
9
10#include <qgl.h>
11
12GLVSyncTestRenderer::GLVSyncTestRenderer(
13 WaveformWidgetRenderer* waveformWidgetRenderer)
14 : WaveformRendererSignalBase(waveformWidgetRenderer),
15 m_drawcount(0) {
16}
17
18GLVSyncTestRenderer::~GLVSyncTestRenderer() {
19}
20
21void GLVSyncTestRenderer::onSetup(const QDomNode &node) {
22 Q_UNUSED(node);
23}
24
25inline void setPoint(QPointF& point, qreal x, qreal y) {
26 point.setX(x);
27 point.setY(y);
28}
29
30void GLVSyncTestRenderer::draw(QPainter* painter, QPaintEvent* /*event*/) {
31
32 PerformanceTimer timer;
33 //int t5, t6, t7, t8, t9, t10, t11, t12, t13;
34
35
36 timer.start();
37
38 TrackPointer pTrack = m_waveformRenderer->getTrackInfo();
39 if (!pTrack) {
40 return;
41 }
42
43 const Waveform* waveform = pTrack->getWaveform();
44 if (waveform == NULL) {
45 return;
46 }
47
48 const int dataSize = waveform->getDataSize();
49 if (dataSize <= 1) {
50 return;
51 }
52
53 const WaveformData* data = waveform->data();
54 if (data == NULL) {
55 return;
56 }
57
58 double firstVisualIndex = m_waveformRenderer->getFirstDisplayedPosition() * dataSize;
59 double lastVisualIndex = m_waveformRenderer->getLastDisplayedPosition() * dataSize;
60
61 const int firstIndex = int(firstVisualIndex + 0.5);
62 firstVisualIndex = firstIndex - firstIndex % 2;
63
64 const int lastIndex = int(lastVisualIndex + 0.5);
65 lastVisualIndex = lastIndex + lastIndex % 2;
66
67 //t5 = timer.restart(); // 910
68
69 // Reset device for native painting
70 painter->beginNativePainting();
71
72 //t6 = timer.restart(); // 29,150
73
74 glEnable(GL_BLEND);
75 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
76
77 const QColor& color = m_pColors->getSignalColor();
78
79 //t7 = timer.restart(); // 5,770
80
81 WaveformWidgetFactory* factory = WaveformWidgetFactory::instance();
82 const double visualGain = factory->getVisualGain(::WaveformWidgetFactory::All);
83
84 float maxAll[2];
85
86 glMatrixMode(GL_PROJECTION);
87 glPushMatrix();
88 glLoadIdentity();
89
90 //t8 = timer.restart(); // 2,611
91
92 if (m_alignment == Qt::AlignCenter) {
93 glOrtho(firstVisualIndex, lastVisualIndex, -255.0, 255.0, -10.0, 10.0);
94 } else if (m_alignment == Qt::AlignBottom) {
95 glOrtho(firstVisualIndex, lastVisualIndex, 0.0, 255.0, -10.0, 10.0);
96 } else {
97 glOrtho(firstVisualIndex, lastVisualIndex, 255.0, 0.0, -10.0, 10.0);
98 }
99
100 //t9 = timer.restart(); // 1,320
101
102 glMatrixMode(GL_MODELVIEW);
103 glPushMatrix();
104 glLoadIdentity();
105
106 //t10 = timer.restart(); // 915
107
108 if (++m_drawcount & 1) {
109 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
110 glColor3f(1.0f, 1.0f, 1.0f);
111 } else {
112 glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
113 glColor3f(1.0f, 0.0f, 0.0f);
114 }
115 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
116 glRectf(0, 0, 1, 1);
117
118 //t11 = timer.restart(); // 217,985
119
120 glEnd();
121 glPopMatrix();
122 glMatrixMode(GL_PROJECTION);
123 glPopMatrix();
124
125 //t12 = timer.restart(); // 22,426
126 painter->endNativePainting();
127
128 //t13 = timer.restart(); // 1,430
129
130 //qDebug() << t5 << t6 << t7 << t8 << t9 << t10 << t11 << t12 << t13;
131
132 //qDebug() << timer.restart(); // 129,498
133}
0134
=== added file 'mixxx/src/waveform/renderers/glvsynctestrenderer.h'
--- mixxx/src/waveform/renderers/glvsynctestrenderer.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/renderers/glvsynctestrenderer.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,19 @@
1#ifndef GLVSYNCTESTRENDERER_H
2#define GLVSYNCTESTRENDERER_H
3
4#include "waveformrenderersignalbase.h"
5
6class ControlObject;
7
8class GLVSyncTestRenderer : public WaveformRendererSignalBase {
9 public:
10 explicit GLVSyncTestRenderer( WaveformWidgetRenderer* waveformWidgetRenderer);
11 virtual ~GLVSyncTestRenderer();
12
13 virtual void onSetup(const QDomNode &node);
14 virtual void draw(QPainter* painter, QPaintEvent* event);
15 private:
16 int m_drawcount;
17};
18
19#endif // GLVSYNCTESTRENDERER_H
020
=== modified file 'mixxx/src/waveform/renderers/waveformrenderbeat.cpp'
--- mixxx/src/waveform/renderers/waveformrenderbeat.cpp 2013-04-12 15:06:58 +0000
+++ mixxx/src/waveform/renderers/waveformrenderbeat.cpp 2013-05-01 22:08:27 +0000
@@ -74,7 +74,7 @@
7474
75 while (it->hasNext()) {75 while (it->hasNext()) {
76 int beatPosition = it->next();76 int beatPosition = it->next();
77 m_waveformRenderer->regulateVisualSample(beatPosition);77 // m_waveformRenderer->regulateVisualSample(beatPosition);
78 double xBeatPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(beatPosition);78 double xBeatPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(beatPosition);
7979
80 painter->setPen(beatPen);80 painter->setPen(beatPen);
8181
=== modified file 'mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp'
--- mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp 2013-01-28 13:06:12 +0000
+++ mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp 2013-05-01 22:08:27 +0000
@@ -13,6 +13,8 @@
13#include "widget/wskincolor.h"13#include "widget/wskincolor.h"
14#include "widget/wwidget.h"14#include "widget/wwidget.h"
1515
16#include "util/timer.h"
17
16WaveformRendererEndOfTrack::WaveformRendererEndOfTrack(18WaveformRendererEndOfTrack::WaveformRendererEndOfTrack(
17 WaveformWidgetRenderer* waveformWidgetRenderer)19 WaveformWidgetRenderer* waveformWidgetRenderer)
18 : WaveformRendererAbstract(waveformWidgetRenderer),20 : WaveformRendererAbstract(waveformWidgetRenderer),
@@ -61,14 +63,20 @@
61}63}
6264
63void WaveformRendererEndOfTrack::onResize() {65void WaveformRendererEndOfTrack::onResize() {
64 m_rect = QRect( 0, 0, m_waveformRenderer->getWidth(), m_waveformRenderer->getHeight());
65 m_backRects.resize(4);66 m_backRects.resize(4);
66 for (int i = 0; i < 4; i++) {67 for (int i = 0; i < 4; i++) {
67 m_backRects[i].setTop(0);68 m_backRects[i].setTop(0);
68 m_backRects[i].setBottom(m_waveformRenderer->getHeight());69 m_backRects[i].setBottom(m_waveformRenderer->getHeight());
69 m_backRects[i].setLeft(m_waveformRenderer->getWidth()/2+i*m_waveformRenderer->getWidth()/8);70 m_backRects[i].setLeft(m_waveformRenderer->getWidth()/2 +
71 i*m_waveformRenderer->getWidth()/8);
70 m_backRects[i].setRight(m_waveformRenderer->getWidth());72 m_backRects[i].setRight(m_waveformRenderer->getWidth());
71 }73 }
74 /*
75 m_gradient.setStart(m_waveformRenderer->getWidth()/2, 0);
76 m_gradient.setFinalStop(m_waveformRenderer->getWidth(), 0);
77 m_gradient.setColorAt(0, Qt::transparent);
78 m_gradient.setColorAt(1, m_color);
79 */
72}80}
7381
74void WaveformRendererEndOfTrack::draw(QPainter* painter,82void WaveformRendererEndOfTrack::draw(QPainter* painter,
@@ -121,6 +129,8 @@
121 //qDebug() << "EndOfTrack ON";129 //qDebug() << "EndOfTrack ON";
122 }130 }
123131
132 ScopedTimer t("WaveformRendererEndOfTrack::draw");
133
124 const int elapsed = m_timer.elapsed() % m_blinkingPeriodMillis;134 const int elapsed = m_timer.elapsed() % m_blinkingPeriodMillis;
125135
126 const double blickIntensity = (double)(2 * abs(elapsed - m_blinkingPeriodMillis/2)) /136 const double blickIntensity = (double)(2 * abs(elapsed - m_blinkingPeriodMillis/2)) /
@@ -139,5 +149,9 @@
139 painter->setPen(QPen(Qt::transparent));149 painter->setPen(QPen(Qt::transparent));
140 painter->setBrush(m_color);150 painter->setBrush(m_color);
141 painter->drawRects(m_backRects);151 painter->drawRects(m_backRects);
152 //painter->setOpacity(0.5 * criticalIntensity * blickIntensity);
153 //painter->fillRect(m_waveformRenderer->getWidth()/2, 1,
154 // m_waveformRenderer->getWidth() - 2, m_waveformRenderer->getHeight() - 2,
155 // m_gradient);
142 painter->restore();156 painter->restore();
143}157}
144158
=== modified file 'mixxx/src/waveform/renderers/waveformrendererendoftrack.h'
--- mixxx/src/waveform/renderers/waveformrendererendoftrack.h 2012-12-14 01:26:04 +0000
+++ mixxx/src/waveform/renderers/waveformrendererendoftrack.h 2013-05-01 22:08:27 +0000
@@ -3,6 +3,7 @@
33
4#include <QColor>4#include <QColor>
5#include <QTime>5#include <QTime>
6#include <QLinearGradient>
67
7#include "util.h"8#include "util.h"
8#include "waveformrendererabstract.h"9#include "waveformrendererabstract.h"
@@ -35,9 +36,9 @@
35 int m_blinkingPeriodMillis;36 int m_blinkingPeriodMillis;
36 double m_remainingTimeTriggerSeconds;37 double m_remainingTimeTriggerSeconds;
3738
38 QRect m_rect;
39 QVector<QRect> m_backRects;39 QVector<QRect> m_backRects;
40 QPen m_pen;40 QPen m_pen;
41 QLinearGradient m_gradient;
4142
42 DISALLOW_COPY_AND_ASSIGN(WaveformRendererEndOfTrack);43 DISALLOW_COPY_AND_ASSIGN(WaveformRendererEndOfTrack);
43};44};
4445
=== added file 'mixxx/src/waveform/renderers/waveformrendererhsv.cpp'
--- mixxx/src/waveform/renderers/waveformrendererhsv.cpp 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/renderers/waveformrendererhsv.cpp 2013-05-01 22:08:27 +0000
@@ -0,0 +1,177 @@
1#include "waveformrendererhsv.h"
2
3#include "waveformwidgetrenderer.h"
4#include "waveform/waveform.h"
5#include "waveform/waveformwidgetfactory.h"
6
7#include "widget/wskincolor.h"
8#include "trackinfoobject.h"
9#include "widget/wwidget.h"
10
11#include "defs.h"
12
13#include "controlobjectthreadmain.h"
14
15WaveformRendererHSV::WaveformRendererHSV(
16 WaveformWidgetRenderer* waveformWidgetRenderer)
17 : WaveformRendererSignalBase( waveformWidgetRenderer) {
18}
19
20WaveformRendererHSV::~WaveformRendererHSV() {
21}
22
23void WaveformRendererHSV::onSetup(const QDomNode& node) {
24 Q_UNUSED(node);
25}
26
27void WaveformRendererHSV::draw(QPainter* painter,
28 QPaintEvent* /*event*/) {
29 const TrackPointer trackInfo = m_waveformRenderer->getTrackInfo();
30 if (!trackInfo) {
31 return;
32 }
33
34 const Waveform* waveform = trackInfo->getWaveform();
35 if (waveform == NULL) {
36 return;
37 }
38
39 const int dataSize = waveform->getDataSize();
40 if (dataSize <= 1) {
41 return;
42 }
43
44 const WaveformData* data = waveform->data();
45 if (data == NULL) {
46 return;
47 }
48
49 painter->save();
50 painter->setRenderHints(QPainter::Antialiasing, false);
51 painter->setRenderHints(QPainter::HighQualityAntialiasing, false);
52 painter->setRenderHints(QPainter::SmoothPixmapTransform, false);
53 painter->setWorldMatrixEnabled(false);
54 painter->resetTransform();
55
56 const double firstVisualIndex = m_waveformRenderer->getFirstDisplayedPosition() * dataSize;
57 const double lastVisualIndex = m_waveformRenderer->getLastDisplayedPosition() * dataSize;
58
59 const double offset = firstVisualIndex;
60
61 // Represents the # of waveform data points per horizontal pixel.
62 const double gain = (lastVisualIndex - firstVisualIndex) /
63 (double)m_waveformRenderer->getWidth();
64
65 float allGain(1.0);
66 allGain = m_waveformRenderer->getGain();
67
68 WaveformWidgetFactory* factory = WaveformWidgetFactory::instance();
69 allGain *= factory->getVisualGain(::WaveformWidgetFactory::All);
70
71 // Save HSV of waveform color
72 double h,s,v;
73
74 // Get base color of waveform in the HSV format (s and v isn't use)
75 m_pColors->getLowColor().getHsvF(&h,&s,&v);
76
77 QColor color;
78 float lo, hi, total;
79
80 const float halfHeight = (float)m_waveformRenderer->getHeight()/2.0;
81
82 const float heightFactor = allGain*halfHeight/255.0;
83
84 //draw reference line
85 painter->setPen(m_axesColor);
86 painter->drawLine(0,halfHeight,m_waveformRenderer->getWidth(),halfHeight);
87
88 for (int x = 0; x < m_waveformRenderer->getWidth(); ++x) {
89 // Width of the x position in visual indices.
90 const double xSampleWidth = gain * x;
91
92 // Effective visual index of x
93 const double xVisualSampleIndex = xSampleWidth + offset;
94
95 // Our current pixel (x) corresponds to a number of visual samples
96 // (visualSamplerPerPixel) in our waveform object. We take the max of
97 // all the data points on either side of xVisualSampleIndex within a
98 // window of 'maxSamplingRange' visual samples to measure the maximum
99 // data point contained by this pixel.
100 double maxSamplingRange = gain / 2.0;
101
102 // Since xVisualSampleIndex is in visual-samples (e.g. R,L,R,L) we want
103 // to check +/- maxSamplingRange frames, not samples. To do this, divide
104 // xVisualSampleIndex by 2. Since frames indices are integers, we round
105 // to the nearest integer by adding 0.5 before casting to int.
106 int visualFrameStart = int(xVisualSampleIndex / 2.0 - maxSamplingRange + 0.5);
107 int visualFrameStop = int(xVisualSampleIndex / 2.0 + maxSamplingRange + 0.5);
108 const int lastVisualFrame = dataSize / 2 - 1;
109
110 // We now know that some subset of [visualFrameStart, visualFrameStop]
111 // lies within the valid range of visual frames. Clamp
112 // visualFrameStart/Stop to within [0, lastVisualFrame].
113 visualFrameStart = math_max(math_min(lastVisualFrame, visualFrameStart), 0);
114 visualFrameStop = math_max(math_min(lastVisualFrame, visualFrameStop), 0);
115
116 int visualIndexStart = visualFrameStart * 2;
117 int visualIndexStop = visualFrameStop * 2;
118
119 int maxLow[2] = {0, 0};
120 int maxHigh[2] = {0, 0};
121 int maxMid[2] = {0, 0};
122 int maxAll[2] = {0, 0};
123
124 for (int i = visualIndexStart;
125 i >= 0 && i + 1 < dataSize && i + 1 <= visualIndexStop; i += 2) {
126 const WaveformData& waveformData = *(data + i);
127 const WaveformData& waveformDataNext = *(data + i + 1);
128 maxLow[0] = math_max(maxLow[0], (int)waveformData.filtered.low);
129 maxLow[1] = math_max(maxLow[1], (int)waveformDataNext.filtered.low);
130 maxMid[0] = math_max(maxMid[0], (int)waveformData.filtered.mid);
131 maxMid[1] = math_max(maxMid[1], (int)waveformDataNext.filtered.mid);
132 maxHigh[0] = math_max(maxHigh[0], (int)waveformData.filtered.high);
133 maxHigh[1] = math_max(maxHigh[1], (int)waveformDataNext.filtered.high);
134 maxAll[0] = math_max( maxAll[0], (int)waveformData.filtered.all);
135 maxAll[1] = math_max( maxAll[1], (int)waveformDataNext.filtered.all);
136 }
137
138 if( maxAll[0] && maxAll[1] ) {
139 // Calculate sum, to normalize
140 // Also multiply on 1.2 to prevent very dark or light color
141 total = (maxLow[0] + maxLow[1] + maxMid[0] + maxMid[1] + maxHigh[0] + maxHigh[1]) * 1.2;
142
143 // prevent division by zero
144 if( total > 0 )
145 {
146 // Normalize low and high (mid not need, because it not change the color)
147 lo = (maxLow[0] + maxLow[1]) / total;
148 hi = (maxHigh[0] + maxHigh[1]) / total;
149 }
150 else
151 lo = hi = 0.0;
152
153 // Set color
154 color.setHsvF(h, 1.0-hi, 1.0-lo);
155
156 painter->setPen(color);
157 switch (m_alignment) {
158 case Qt::AlignBottom :
159 painter->drawLine(
160 x, m_waveformRenderer->getHeight(),
161 x, m_waveformRenderer->getHeight() - (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1])));
162 break;
163 case Qt::AlignTop :
164 painter->drawLine(
165 x, 0,
166 x, (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1])));
167 break;
168 default :
169 painter->drawLine(
170 x, (int)(halfHeight-heightFactor*(float)maxAll[0]),
171 x, (int)(halfHeight+heightFactor*(float)maxAll[1]));
172 }
173 }
174 }
175
176 painter->restore();
177}
0178
=== removed file 'mixxx/src/waveform/renderers/waveformrendererhsv.cpp'
--- mixxx/src/waveform/renderers/waveformrendererhsv.cpp 2013-01-16 21:03:36 +0000
+++ mixxx/src/waveform/renderers/waveformrendererhsv.cpp 1970-01-01 00:00:00 +0000
@@ -1,177 +0,0 @@
1#include "waveformrendererhsv.h"
2
3#include "waveformwidgetrenderer.h"
4#include "waveform/waveform.h"
5#include "waveform/waveformwidgetfactory.h"
6
7#include "widget/wskincolor.h"
8#include "trackinfoobject.h"
9#include "widget/wwidget.h"
10
11#include "defs.h"
12
13#include "controlobjectthreadmain.h"
14
15WaveformRendererHSV::WaveformRendererHSV(
16 WaveformWidgetRenderer* waveformWidgetRenderer)
17 : WaveformRendererSignalBase( waveformWidgetRenderer) {
18}
19
20WaveformRendererHSV::~WaveformRendererHSV() {
21}
22
23void WaveformRendererHSV::onSetup(const QDomNode& node) {
24 Q_UNUSED(node);
25}
26
27void WaveformRendererHSV::draw(QPainter* painter,
28 QPaintEvent* /*event*/) {
29 const TrackPointer trackInfo = m_waveformRenderer->getTrackInfo();
30 if (!trackInfo) {
31 return;
32 }
33
34 const Waveform* waveform = trackInfo->getWaveform();
35 if (waveform == NULL) {
36 return;
37 }
38
39 const int dataSize = waveform->getDataSize();
40 if (dataSize <= 1) {
41 return;
42 }
43
44 const WaveformData* data = waveform->data();
45 if (data == NULL) {
46 return;
47 }
48
49 painter->save();
50 painter->setRenderHints(QPainter::Antialiasing, false);
51 painter->setRenderHints(QPainter::HighQualityAntialiasing, false);
52 painter->setRenderHints(QPainter::SmoothPixmapTransform, false);
53 painter->setWorldMatrixEnabled(false);
54 painter->resetTransform();
55
56 const double firstVisualIndex = m_waveformRenderer->getFirstDisplayedPosition() * dataSize;
57 const double lastVisualIndex = m_waveformRenderer->getLastDisplayedPosition() * dataSize;
58
59 const double offset = firstVisualIndex;
60
61 // Represents the # of waveform data points per horizontal pixel.
62 const double gain = (lastVisualIndex - firstVisualIndex) /
63 (double)m_waveformRenderer->getWidth();
64
65 float allGain(1.0);
66 allGain = m_waveformRenderer->getGain();
67
68 WaveformWidgetFactory* factory = WaveformWidgetFactory::instance();
69 allGain *= factory->getVisualGain(::WaveformWidgetFactory::All);
70
71 // Save HSV of waveform color
72 double h,s,v;
73
74 // Get base color of waveform in the HSV format (s and v isn't use)
75 m_pColors->getLowColor().getHsvF(&h,&s,&v);
76
77 QColor color;
78 float lo, hi, total;
79
80 const float halfHeight = (float)m_waveformRenderer->getHeight()/2.0;
81
82 const float heightFactor = allGain*halfHeight/255.0;
83
84 //draw reference line
85 painter->setPen(m_axesColor);
86 painter->drawLine(0,halfHeight,m_waveformRenderer->getWidth(),halfHeight);
87
88 for (int x = 0; x < m_waveformRenderer->getWidth(); ++x) {
89 // Width of the x position in visual indices.
90 const double xSampleWidth = gain * x;
91
92 // Effective visual index of x
93 const double xVisualSampleIndex = xSampleWidth + offset;
94
95 // Our current pixel (x) corresponds to a number of visual samples
96 // (visualSamplerPerPixel) in our waveform object. We take the max of
97 // all the data points on either side of xVisualSampleIndex within a
98 // window of 'maxSamplingRange' visual samples to measure the maximum
99 // data point contained by this pixel.
100 double maxSamplingRange = gain / 2.0;
101
102 // Since xVisualSampleIndex is in visual-samples (e.g. R,L,R,L) we want
103 // to check +/- maxSamplingRange frames, not samples. To do this, divide
104 // xVisualSampleIndex by 2. Since frames indices are integers, we round
105 // to the nearest integer by adding 0.5 before casting to int.
106 int visualFrameStart = int(xVisualSampleIndex / 2.0 - maxSamplingRange + 0.5);
107 int visualFrameStop = int(xVisualSampleIndex / 2.0 + maxSamplingRange + 0.5);
108 const int lastVisualFrame = dataSize / 2 - 1;
109
110 // We now know that some subset of [visualFrameStart, visualFrameStop]
111 // lies within the valid range of visual frames. Clamp
112 // visualFrameStart/Stop to within [0, lastVisualFrame].
113 visualFrameStart = math_max(math_min(lastVisualFrame, visualFrameStart), 0);
114 visualFrameStop = math_max(math_min(lastVisualFrame, visualFrameStop), 0);
115
116 int visualIndexStart = visualFrameStart * 2;
117 int visualIndexStop = visualFrameStop * 2;
118
119 int maxLow[2] = {0, 0};
120 int maxHigh[2] = {0, 0};
121 int maxMid[2] = {0, 0};
122 int maxAll[2] = {0, 0};
123
124 for (int i = visualIndexStart;
125 i >= 0 && i + 1 < dataSize && i + 1 <= visualIndexStop; i += 2) {
126 const WaveformData& waveformData = *(data + i);
127 const WaveformData& waveformDataNext = *(data + i + 1);
128 maxLow[0] = math_max(maxLow[0], (int)waveformData.filtered.low);
129 maxLow[1] = math_max(maxLow[1], (int)waveformDataNext.filtered.low);
130 maxMid[0] = math_max(maxMid[0], (int)waveformData.filtered.mid);
131 maxMid[1] = math_max(maxMid[1], (int)waveformDataNext.filtered.mid);
132 maxHigh[0] = math_max(maxHigh[0], (int)waveformData.filtered.high);
133 maxHigh[1] = math_max(maxHigh[1], (int)waveformDataNext.filtered.high);
134 maxAll[0] = math_max( maxAll[0], (int)waveformData.filtered.all);
135 maxAll[1] = math_max( maxAll[1], (int)waveformDataNext.filtered.all);
136 }
137
138 if( maxAll[0] && maxAll[1] ) {
139 // Calculate sum, to normalize
140 // Also multiply on 1.2 to prevent very dark or light color
141 total = (maxLow[0] + maxLow[1] + maxMid[0] + maxMid[1] + maxHigh[0] + maxHigh[1]) * 1.2;
142
143 // prevent division by zero
144 if( total > 0 )
145 {
146 // Normalize low and high (mid not need, because it not change the color)
147 lo = (maxLow[0] + maxLow[1]) / total;
148 hi = (maxHigh[0] + maxHigh[1]) / total;
149 }
150 else
151 lo = hi = 0.0;
152
153 // Set color
154 color.setHsvF(h, 1.0-hi, 1.0-lo);
155
156 painter->setPen(color);
157 switch (m_alignment) {
158 case Qt::AlignBottom :
159 painter->drawLine(
160 x, m_waveformRenderer->getHeight(),
161 x, m_waveformRenderer->getHeight() - (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1])));
162 break;
163 case Qt::AlignTop :
164 painter->drawLine(
165 x, 0,
166 x, (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1])));
167 break;
168 default :
169 painter->drawLine(
170 x, (int)(halfHeight-heightFactor*(float)maxAll[0]),
171 x, (int)(halfHeight+heightFactor*(float)maxAll[1]));
172 }
173 }
174 }
175
176 painter->restore();
177}
1780
=== added file 'mixxx/src/waveform/renderers/waveformrendererhsv.h'
--- mixxx/src/waveform/renderers/waveformrendererhsv.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/renderers/waveformrendererhsv.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,21 @@
1#ifndef WAVEFORMRENDERERHSV_H
2#define WAVEFORMRENDERERHSV_H
3
4#include "waveformrenderersignalbase.h"
5#include "util.h"
6
7class WaveformRendererHSV : public WaveformRendererSignalBase {
8 public:
9 explicit WaveformRendererHSV(
10 WaveformWidgetRenderer* waveformWidget);
11 virtual ~WaveformRendererHSV();
12
13 virtual void onSetup(const QDomNode& node);
14
15 virtual void draw(QPainter* painter, QPaintEvent* event);
16
17 private:
18 DISALLOW_COPY_AND_ASSIGN(WaveformRendererHSV);
19};
20
21#endif // WAVEFORMRENDERERFILTEREDSIGNAL_H
022
=== removed file 'mixxx/src/waveform/renderers/waveformrendererhsv.h'
--- mixxx/src/waveform/renderers/waveformrendererhsv.h 2012-12-14 01:26:04 +0000
+++ mixxx/src/waveform/renderers/waveformrendererhsv.h 1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
1#ifndef WAVEFORMRENDERERHSV_H
2#define WAVEFORMRENDERERHSV_H
3
4#include "waveformrenderersignalbase.h"
5#include "util.h"
6
7class WaveformRendererHSV : public WaveformRendererSignalBase {
8 public:
9 explicit WaveformRendererHSV(
10 WaveformWidgetRenderer* waveformWidget);
11 virtual ~WaveformRendererHSV();
12
13 virtual void onSetup(const QDomNode& node);
14
15 virtual void draw(QPainter* painter, QPaintEvent* event);
16
17 private:
18 DISALLOW_COPY_AND_ASSIGN(WaveformRendererHSV);
19};
20
21#endif // WAVEFORMRENDERERFILTEREDSIGNAL_H
220
=== modified file 'mixxx/src/waveform/renderers/waveformrendererpreroll.cpp'
--- mixxx/src/waveform/renderers/waveformrendererpreroll.cpp 2012-11-20 21:24:37 +0000
+++ mixxx/src/waveform/renderers/waveformrendererpreroll.cpp 2013-05-01 22:08:27 +0000
@@ -29,14 +29,13 @@
29 if (!track) {29 if (!track) {
30 return;30 return;
31 }31 }
32 const Waveform* waveform = track->getWaveform();
33 double samplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel();32 double samplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel();
34 double numberOfSamples = m_waveformRenderer->getWidth() * samplesPerPixel;33 double numberOfSamples = m_waveformRenderer->getWidth() * samplesPerPixel;
3534
36 // TODO (vRince) not really accurate since waveform size une visual reasampling and35 // TODO (vRince) not really accurate since waveform size une visual reasampling and
37 // have two mores samples to hold the complete visual data36 // have two mores samples to hold the complete visual data
38 int currentPosition = m_waveformRenderer->getPlayPos() * waveform->getDataSize();37 int currentPosition = m_waveformRenderer->getPlayPosVSample();
39 m_waveformRenderer->regulateVisualSample(currentPosition);38 // m_waveformRenderer->regulateVisualSample(currentPosition);
4039
41 // Some of the pre-roll is on screen. Draw little triangles to indicate40 // Some of the pre-roll is on screen. Draw little triangles to indicate
42 // where the pre-roll is located.41 // where the pre-roll is located.
@@ -47,6 +46,9 @@
47 const float halfPolyHeight = m_waveformRenderer->getHeight()/5.0;46 const float halfPolyHeight = m_waveformRenderer->getHeight()/5.0;
4847
49 painter->save();48 painter->save();
49 painter->setRenderHint(QPainter::Antialiasing);
50 //painter->setRenderHint(QPainter::HighQualityAntialiasing);
51 //painter->setBackgroundMode(Qt::TransparentMode);
50 painter->setWorldMatrixEnabled(false);52 painter->setWorldMatrixEnabled(false);
51 painter->setPen(QPen(QBrush(m_color), 1));53 painter->setPen(QPen(QBrush(m_color), 1));
52 QPolygonF polygon;54 QPolygonF polygon;
5355
=== modified file 'mixxx/src/waveform/renderers/waveformrendermark.cpp'
--- mixxx/src/waveform/renderers/waveformrendermark.cpp 2013-03-27 21:32:51 +0000
+++ mixxx/src/waveform/renderers/waveformrendermark.cpp 2013-05-01 22:08:27 +0000
@@ -48,8 +48,8 @@
48 }48 }
4949
50 int samplePosition = mark.m_pointControl->get();50 int samplePosition = mark.m_pointControl->get();
51 if (samplePosition >= 0.0) {51 if (samplePosition > 0.0) {
52 m_waveformRenderer->regulateVisualSample(samplePosition);52 //m_waveformRenderer->regulateVisualSample(samplePosition);
53 double currentMarkPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(samplePosition);53 double currentMarkPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(samplePosition);
5454
55 // NOTE: vRince I guess image width is odd to display the center on the exact line !55 // NOTE: vRince I guess image width is odd to display the center on the exact line !
5656
=== modified file 'mixxx/src/waveform/renderers/waveformrendermarkrange.cpp'
--- mixxx/src/waveform/renderers/waveformrendermarkrange.cpp 2013-01-31 19:48:57 +0000
+++ mixxx/src/waveform/renderers/waveformrendermarkrange.cpp 2013-05-01 22:08:27 +0000
@@ -58,10 +58,10 @@
58 int startSample = markRange.start();58 int startSample = markRange.start();
59 int endSample = markRange.end();59 int endSample = markRange.end();
6060
61 m_waveformRenderer->regulateVisualSample(startSample);61 //m_waveformRenderer->regulateVisualSample(startSample);
62 double startPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(startSample);62 double startPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(startSample);
6363
64 m_waveformRenderer->regulateVisualSample(endSample);64 //m_waveformRenderer->regulateVisualSample(endSample);
65 double endPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(endSample);65 double endPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(endSample);
6666
67 //range not in the current display67 //range not in the current display
6868
=== modified file 'mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp'
--- mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp 2013-01-31 21:53:32 +0000
+++ mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp 2013-05-01 22:08:27 +0000
@@ -6,56 +6,49 @@
6#include "controlobjectthreadmain.h"6#include "controlobjectthreadmain.h"
7#include "controlobject.h"7#include "controlobject.h"
8#include "defs.h"8#include "defs.h"
9#include "visualplayposition.h"
9#include "mathstuff.h"10#include "mathstuff.h"
1011
12#include "util/performancetimer.h"
13
14#include <QPainter>
15
11const int WaveformWidgetRenderer::s_waveformMinZoom = 1;16const int WaveformWidgetRenderer::s_waveformMinZoom = 1;
12const int WaveformWidgetRenderer::s_waveformMaxZoom = 6;17const int WaveformWidgetRenderer::s_waveformMaxZoom = 6;
1318
14WaveformWidgetRenderer::WaveformWidgetRenderer() {19WaveformWidgetRenderer::WaveformWidgetRenderer( const char* group)
15 m_playPosControlObject = NULL;20 : m_group(group),
16 m_rateControlObject = NULL;21 m_trackInfoObject(0),
17 m_rateRangeControlObject = NULL;22 m_height(-1),
18 m_rateDirControlObject = NULL;23 m_width(-1),
19 m_gainControlObject = NULL;24
20 m_trackSamplesControlObject = NULL;25 m_firstDisplayedPosition(0.0),
2126 m_lastDisplayedPosition(0.0),
22#ifdef WAVEFORMWIDGETRENDERER_DEBUG27 m_rendererTransformationOffset(0.0),
23 m_timer = NULL;28 m_rendererTransformationGain(0.0),
24#endif29
25}30 m_zoomFactor(1.0),
2631 m_rateAdjust(0.0),
27WaveformWidgetRenderer::WaveformWidgetRenderer( const char* group) :32 m_visualSamplePerPixel(1.0),
28 m_group(group),33 m_audioSamplePerPixel(1.0),
29 m_trackInfoObject(0),34
30 m_height(-1),35 // Really create some to manage those;
31 m_width(-1) {36 m_visualPlayPosition(NULL),
37 m_playPos(-1),
38 m_playPosVSample(0),
39 m_rateControlObject(NULL),
40 m_rate(0.0),
41 m_rateRangeControlObject(NULL),
42 m_rateRange(0.0),
43 m_rateDirControlObject(NULL),
44 m_rateDir(0.0),
45 m_gainControlObject(NULL),
46 m_gain(1.0),
47 m_trackSamplesControlObject(NULL),
48 m_trackSamples(0.0) {
49
32 //qDebug() << "WaveformWidgetRenderer";50 //qDebug() << "WaveformWidgetRenderer";
3351
34 m_firstDisplayedPosition = 0.0;
35 m_lastDisplayedPosition = 0.0;
36 m_rendererTransformationOffset = 0.0;
37 m_rendererTransformationGain = 0.0;
38
39 m_zoomFactor = 1.0;
40 m_rateAdjust = 0.0;
41 m_visualSamplePerPixel = 1.0;
42 m_audioSamplePerPixel = 1.0;
43
44 // Really create some to manage those
45 m_playPosControlObject = NULL;
46 m_playPos = 0.0;
47 m_rateControlObject = NULL;
48 m_rate = 0.0;
49 m_rateRangeControlObject = NULL;
50 m_rateRange = 0.0;
51 m_rateDirControlObject = NULL;
52 m_rateDir = 0.0;
53 m_gainControlObject = NULL;
54 m_gain = 1.0;
55 m_trackSamplesControlObject = NULL;
56 m_trackSamples = -1.0;
57
58
59#ifdef WAVEFORMWIDGETRENDERER_DEBUG52#ifdef WAVEFORMWIDGETRENDERER_DEBUG
60 m_timer = new QTime();53 m_timer = new QTime();
61 currentFrame = 0;54 currentFrame = 0;
@@ -74,7 +67,6 @@
74 for( int i = 0; i < m_rendererStack.size(); ++i)67 for( int i = 0; i < m_rendererStack.size(); ++i)
75 delete m_rendererStack[i];68 delete m_rendererStack[i];
7669
77 delete m_playPosControlObject;
78 delete m_rateControlObject;70 delete m_rateControlObject;
79 delete m_rateRangeControlObject;71 delete m_rateRangeControlObject;
80 delete m_rateDirControlObject;72 delete m_rateDirControlObject;
@@ -89,9 +81,8 @@
89bool WaveformWidgetRenderer::init() {81bool WaveformWidgetRenderer::init() {
9082
91 //qDebug() << "WaveformWidgetRenderer::init";83 //qDebug() << "WaveformWidgetRenderer::init";
84 m_visualPlayPosition = VisualPlayPosition::getVisualPlayPosition(m_group);
9285
93 m_playPosControlObject = new ControlObjectThreadMain(
94 ControlObject::getControl( ConfigKey(m_group, "visual_playposition")));
95 m_rateControlObject = new ControlObjectThreadMain(86 m_rateControlObject = new ControlObjectThreadMain(
96 ControlObject::getControl( ConfigKey(m_group, "rate")));87 ControlObject::getControl( ConfigKey(m_group, "rate")));
97 m_rateRangeControlObject = new ControlObjectThreadMain(88 m_rateRangeControlObject = new ControlObjectThreadMain(
@@ -111,7 +102,7 @@
111 return true;102 return true;
112}103}
113104
114void WaveformWidgetRenderer::onPreRender() {105void WaveformWidgetRenderer::onPreRender(VSyncThread* vsyncThread) {
115 // For a valid track to render we need106 // For a valid track to render we need
116 m_trackSamples = m_trackSamplesControlObject->get();107 m_trackSamples = m_trackSamplesControlObject->get();
117 if (m_trackSamples <= 0.0) {108 if (m_trackSamples <= 0.0) {
@@ -141,7 +132,7 @@
141 m_audioSamplePerPixel = 0.0;132 m_audioSamplePerPixel = 0.0;
142 }133 }
143134
144 m_playPos = m_playPosControlObject->get();135 m_playPos = m_visualPlayPosition->getAt(vsyncThread);
145 // m_playPos = -1 happens, when a new track is in buffer but m_visualPlayPosition was not updated136 // m_playPos = -1 happens, when a new track is in buffer but m_visualPlayPosition was not updated
146137
147 if (m_audioSamplePerPixel && m_playPos != -1) {138 if (m_audioSamplePerPixel && m_playPos != -1) {
@@ -153,7 +144,9 @@
153 double displayedLengthHalf = static_cast<double>(m_width) / trackPixel / 2.0;144 double displayedLengthHalf = static_cast<double>(m_width) / trackPixel / 2.0;
154 // Avoid pixel jitter in play position by rounding to the nearest track145 // Avoid pixel jitter in play position by rounding to the nearest track
155 // pixel.146 // pixel.
156 m_playPos = round(m_playPosControlObject->get() * trackPixel) / trackPixel;147 m_playPos = round(m_playPos * trackPixel)/(double)trackPixel; // Avoid pixel jitter in play position
148 m_playPosVSample = m_playPos * m_trackInfoObject->getWaveform()->getDataSize();
149
157 m_firstDisplayedPosition = m_playPos - displayedLengthHalf;150 m_firstDisplayedPosition = m_playPos - displayedLengthHalf;
158 m_lastDisplayedPosition = m_playPos + displayedLengthHalf;151 m_lastDisplayedPosition = m_playPos + displayedLengthHalf;
159 m_rendererTransformationOffset = - m_firstDisplayedPosition;152 m_rendererTransformationOffset = - m_firstDisplayedPosition;
@@ -181,6 +174,9 @@
181 m_lastSystemFrameTime = m_timer->restart();174 m_lastSystemFrameTime = m_timer->restart();
182#endif175#endif
183176
177// PerformanceTimer timer;
178// timer.start();
179
184 //not ready to display need to wait until track initialization is done180 //not ready to display need to wait until track initialization is done
185 //draw only first is stack (background)181 //draw only first is stack (background)
186 int stackSize = m_rendererStack.size();182 int stackSize = m_rendererStack.size();
@@ -191,7 +187,9 @@
191 return;187 return;
192 } else {188 } else {
193 for (int i = 0; i < stackSize; i++) {189 for (int i = 0; i < stackSize; i++) {
190 // qDebug() << i << " a " << timer.restart();
194 m_rendererStack.at(i)->draw(painter, event);191 m_rendererStack.at(i)->draw(painter, event);
192 // qDebug() << i << " e " << timer.restart();
195 }193 }
196194
197 painter->setPen(m_colors.getPlayPosColor());195 painter->setPen(m_colors.getPlayPosColor());
@@ -215,7 +213,8 @@
215 QString::number(m_lastFrameTime).rightJustified(2,'0') + "(" +213 QString::number(m_lastFrameTime).rightJustified(2,'0') + "(" +
216 QString::number(frameMax).rightJustified(2,'0') + ")" +214 QString::number(frameMax).rightJustified(2,'0') + ")" +
217 QString::number(m_lastSystemFrameTime) + "(" +215 QString::number(m_lastSystemFrameTime) + "(" +
218 QString::number(systemMax) + ")");216 QString::number(systemMax) + ")" +
217 QString::number(realtimeError));
219218
220 painter->drawText(1,m_height-1,219 painter->drawText(1,m_height-1,
221 QString::number(m_playPos) + " [" +220 QString::number(m_playPos) + " [" +
@@ -234,6 +233,7 @@
234 m_lastFramesTime[currentFrame] = m_lastFrameTime;233 m_lastFramesTime[currentFrame] = m_lastFrameTime;
235#endif234#endif
236235
236 // qDebug() << "draw() ende" << timer.restart();
237}237}
238238
239void WaveformWidgetRenderer::resize( int width, int height) {239void WaveformWidgetRenderer::resize( int width, int height) {
240240
=== modified file 'mixxx/src/waveform/renderers/waveformwidgetrenderer.h'
--- mixxx/src/waveform/renderers/waveformwidgetrenderer.h 2013-01-31 21:53:32 +0000
+++ mixxx/src/waveform/renderers/waveformwidgetrenderer.h 2013-05-01 22:08:27 +0000
@@ -15,6 +15,8 @@
1515
16class TrackInfoObject;16class TrackInfoObject;
17class ControlObjectThreadMain;17class ControlObjectThreadMain;
18class VisualPlayPosition;
19class VSyncThread;
1820
19class WaveformWidgetRenderer {21class WaveformWidgetRenderer {
20public:22public:
@@ -29,7 +31,7 @@
29 virtual bool onInit() {return true;}31 virtual bool onInit() {return true;}
3032
31 void setup(const QDomNode& node);33 void setup(const QDomNode& node);
32 void onPreRender();34 void onPreRender(VSyncThread* vsyncThread);
33 void draw(QPainter* painter, QPaintEvent* event);35 void draw(QPainter* painter, QPaintEvent* event);
3436
35 const char* getGroup() const { return m_group;}37 const char* getGroup() const { return m_group;}
@@ -56,6 +58,7 @@
56 double transformPositionInRendererWorld(double position) const;58 double transformPositionInRendererWorld(double position) const;
5759
58 double getPlayPos() const { return m_playPos;}60 double getPlayPos() const { return m_playPos;}
61 double getPlayPosVSample() const { return m_playPosVSample;}
59 double getZoomFactor() const { return m_zoomFactor;}62 double getZoomFactor() const { return m_zoomFactor;}
60 double getRateAdjust() const { return m_rateAdjust;}63 double getRateAdjust() const { return m_rateAdjust;}
61 double getGain() const { return m_gain;}64 double getGain() const { return m_gain;}
@@ -78,7 +81,7 @@
78protected:81protected:
79 const char* m_group;82 const char* m_group;
80 TrackPointer m_trackInfoObject;83 TrackPointer m_trackInfoObject;
81 QVector<WaveformRendererAbstract*> m_rendererStack;84 QList<WaveformRendererAbstract*> m_rendererStack;
82 int m_height;85 int m_height;
83 int m_width;86 int m_width;
84 WaveformSignalColors m_colors;87 WaveformSignalColors m_colors;
@@ -95,8 +98,9 @@
9598
96 //TODO: vRince create some class to manage control/value99 //TODO: vRince create some class to manage control/value
97 //ControlConnection100 //ControlConnection
98 ControlObjectThreadMain* m_playPosControlObject;101 VisualPlayPosition* m_visualPlayPosition;
99 double m_playPos;102 double m_playPos;
103 int m_playPosVSample;
100 ControlObjectThreadMain* m_rateControlObject;104 ControlObjectThreadMain* m_rateControlObject;
101 double m_rate;105 double m_rate;
102 ControlObjectThreadMain* m_rateRangeControlObject;106 ControlObjectThreadMain* m_rateRangeControlObject;
@@ -117,7 +121,6 @@
117 int currentFrame;121 int currentFrame;
118#endif122#endif
119123
120 WaveformWidgetRenderer();
121private:124private:
122 DISALLOW_COPY_AND_ASSIGN(WaveformWidgetRenderer);125 DISALLOW_COPY_AND_ASSIGN(WaveformWidgetRenderer);
123 friend class WaveformWidgetFactory;126 friend class WaveformWidgetFactory;
124127
=== added file 'mixxx/src/waveform/vsyncthread.cpp'
--- mixxx/src/waveform/vsyncthread.cpp 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/vsyncthread.cpp 2013-05-01 22:08:27 +0000
@@ -0,0 +1,179 @@
1
2#include <QThread>
3#include <QGLWidget>
4#include <QGLFormat>
5#include <QTime>
6#include <qdebug.h>
7#include <QTime>
8
9#include "mathstuff.h"
10#include "vsyncthread.h"
11#include "util/performancetimer.h"
12
13#if defined(__APPLE__)
14
15#elif defined(__WINDOWS__)
16
17#else
18 extern const QX11Info *qt_x11Info(const QPaintDevice *pd);
19#endif
20
21VSyncThread::VSyncThread(QWidget* parent)
22 : QThread(),
23 m_firstRun(false),
24 m_usSyncTime(33333),
25 m_vSyncMode(ST_TIMER),
26 m_syncOk(false),
27 m_rtErrorCnt(0),
28 m_swapWait(0),
29 m_displayFrameRate(60.0),
30 m_interval(1) {
31 doRendering = true;
32}
33
34VSyncThread::~VSyncThread() {
35 doRendering = false;
36 m_sema.release(2); // Two slots
37 wait();
38 //delete m_glw;
39}
40
41void VSyncThread::stop()
42{
43 doRendering = false;
44}
45
46
47void VSyncThread::run() {
48 QThread::currentThread()->setObjectName("VSyncThread");
49
50 int usRest;
51 int usLast;
52
53 m_usWait = m_usSyncTime;
54 m_timer.start();
55
56 while (doRendering) {
57 if (m_vSyncMode == ST_FREE) {
58 // for benchmark only!
59 emit(vsync1()); // renders the waveform, Possible delayed due to anti tearing
60 m_sema.acquire();
61 emit(vsync2()); // swaps the new waveform to front
62 m_sema.acquire();
63 m_timer.restart();
64 m_usWait = 1000;
65 usleep(1000);
66 } else { // if (m_vSyncMode == ST_TIMER) {
67 usRest = m_usWait - m_timer.elapsed() / 1000;
68 // waiting for interval by sleep
69 if (usRest > 100) {
70 usleep(usRest);
71 }
72
73 emit(vsync2()); // swaps the new waveform to front in case of gl-wf
74 m_sema.acquire(); // wait until swap was scheduled. It might be delayed due to driver vSync settings
75 // <- Assume we are VSynced here ->
76 usLast = m_timer.restart() / 1000;
77 if (usRest < 0) {
78 // Our swapping call was already delayed
79 // The real swap might happens on the following VSync, depending on driver settings
80 m_rtErrorCnt++; // Count as Real Time Error
81 }
82 // try to stay in right intervals
83 usRest = m_usWait - usLast;
84 m_usWait = m_usSyncTime + (usRest % m_usSyncTime);
85 emit(vsync1()); // renders the new waveform.
86 m_sema.acquire(); // wait until rendreing was scheduled. It might be delayed due a pending swap (depends one driver vSync settings)
87 // qDebug() << "ST_TIMER " << usLast << usRest;
88 }
89 }
90}
91
92
93void VSyncThread::postRender(QGLWidget* glw, int index) {
94 // No need for glw->makeCurrent() here.
95// qDebug() << "postRender" << m_timer.elapsed();
96#if defined(__APPLE__)
97 glw->swapBuffers();
98#elif defined(__WINDOWS__)
99 glw->swapBuffers();
100#else
101 const QX11Info *xinfo = qt_x11Info(glw);
102 glXSwapBuffers(xinfo->display(), glw->winId());
103#endif
104}
105
106int VSyncThread::elapsed() {
107 return m_timer.elapsed() / 1000;
108}
109
110void VSyncThread::setUsSyncTime(int syncTime) {
111 m_usSyncTime = syncTime;
112 double frameRate = 60.0;
113 m_interval = round(m_displayFrameRate * m_usSyncTime / 1000);
114}
115
116void VSyncThread::setVSyncType(int type) {
117 if (type >= (int)VSyncThread::ST_COUNT) {
118 type = VSyncThread::ST_TIMER;
119 }
120 m_vSyncMode = (enum VSyncMode)type;
121 m_rtErrorCnt = 0;
122 m_firstRun = true;
123}
124
125int VSyncThread::usToNextSync() {
126 int usRest = m_usWait - m_timer.elapsed() / 1000;
127 if (usRest < 0) {
128 usRest %= m_usSyncTime;
129 usRest += m_usSyncTime;
130 }
131 return usRest;
132}
133
134int VSyncThread::usFromTimerToNextSync(PerformanceTimer* timer) {
135 int difference = m_timer.difference(timer) / 1000;
136 return difference + m_usWait;
137}
138
139int VSyncThread::rtErrorCnt() {
140 return m_rtErrorCnt;
141}
142
143void VSyncThread::vsyncSlotFinished() {
144 m_sema.release();
145}
146
147void VSyncThread::getAvailableVSyncTypes(QList<QPair<int, QString > >* pList) {
148 QPair<int, QString > pair;
149
150 for (int i = (int)VSyncThread::ST_TIMER; i < (int)VSyncThread::ST_COUNT; i++) {
151 //if (isAvailable(type)) // TODO
152 {
153 enum VSyncMode mode = (enum VSyncMode)i;
154
155 QString name;
156 switch (mode) {
157 case VSyncThread::ST_TIMER:
158 name = tr("Timer (Fallback)");
159 break;
160 case VSyncThread::ST_MESA_VBLANK_MODE_1:
161 name = tr("MESA vblank_mode = 1");
162 break;
163 case VSyncThread::ST_SGI_VIDEO_SYNC:
164 name = tr("Wait for Video sync");
165 break;
166 case VSyncThread::ST_OML_SYNC_CONTROL:
167 name = tr("Sync Control");
168 break;
169 case VSyncThread::ST_FREE:
170 name = tr("Free + 1 ms (for benchmark only)");
171 break;
172 default:
173 break;
174 }
175 QPair<int, QString > pair = QPair<int, QString >(i, name);
176 pList->append(pair);
177 }
178 }
179}
0180
=== added file 'mixxx/src/waveform/vsyncthread.h'
--- mixxx/src/waveform/vsyncthread.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/vsyncthread.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,109 @@
1#ifndef VSYNCTHREAD_H
2#define VSYNCTHREAD_H
3
4#include <QTime>
5#include <QThread>
6#include <QSemaphore>
7#include <QPair>
8
9#include <qx11info_x11.h>
10#include "util/performancetimer.h"
11
12
13#if defined(__APPLE__)
14
15#elif defined(__WINDOWS__)
16
17#else
18 #include <GL/glx.h>
19 #include "GL/glxext.h"
20#endif
21
22
23class QGLWidget;
24
25class VSyncThread : public QThread {
26 Q_OBJECT
27 public:
28 enum VSyncMode {
29 ST_TIMER = 0,
30 ST_MESA_VBLANK_MODE_1,
31 ST_SGI_VIDEO_SYNC,
32 ST_OML_SYNC_CONTROL,
33 ST_FREE,
34 ST_COUNT // Dummy Type at last, counting possible types
35 };
36
37 VSyncThread(QWidget* parent);
38 ~VSyncThread();
39 void run();
40 void stop();
41
42 bool waitForVideoSync(QGLWidget* glw);
43 int elapsed();
44 int usToNextSync();
45 void setUsSyncTime(int usSyncTimer);
46 void setVSyncType(int mode);
47 int rtErrorCnt();
48 void setSwapWait(int sw);
49 int usFromTimerToNextSync(PerformanceTimer* timer);
50 void vsyncSlotFinished();
51 void getAvailableVSyncTypes(QList<QPair<int, QString > >* list);
52 void setupSync(QGLWidget* glw, int index);
53 void postRender(QGLWidget* glw, int index);
54 void waitUntilSwap(QGLWidget* glw);
55
56 signals:
57 void vsync1();
58 void vsync2();
59
60 private:
61 bool doRendering;
62 QGLWidget *m_glw;
63
64#if defined(__APPLE__)
65
66#elif defined(__WINDOWS__)
67
68#else
69 void initGlxext(QGLWidget* glw);
70 bool glXExtensionSupported(Display *dpy, int screen, const char *extension);
71
72 PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI;
73 PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI;
74
75 PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI;
76
77 PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT;
78
79 PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML;
80 PFNGLXGETMSCRATEOMLPROC glXGetMscRateOML;
81 PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML;
82 PFNGLXWAITFORMSCOMLPROC glXWaitForMscOML;
83 PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML;
84
85 PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA;
86
87 uint m_counter;
88
89 int64_t m_target_msc;
90 Display* m_dpy;
91 GLXDrawable m_drawable;
92
93#endif
94
95 bool m_firstRun;
96 int m_usSyncTime;
97 int m_usWait;
98 enum VSyncMode m_vSyncMode;
99 bool m_syncOk;
100 int m_rtErrorCnt;
101 int m_swapWait;
102 PerformanceTimer m_timer;
103 QSemaphore m_sema;
104 double m_displayFrameRate;
105 int m_interval;
106};
107
108
109#endif // VSYNCTHREAD_H
0110
=== modified file 'mixxx/src/waveform/waveformwidgetfactory.cpp'
--- mixxx/src/waveform/waveformwidgetfactory.cpp 2012-12-13 22:46:16 +0000
+++ mixxx/src/waveform/waveformwidgetfactory.cpp 2013-05-01 22:08:27 +0000
@@ -18,8 +18,13 @@
18#include "waveform/widgets/qtwaveformwidget.h"18#include "waveform/widgets/qtwaveformwidget.h"
19#include "waveform/widgets/qtsimplewaveformwidget.h"19#include "waveform/widgets/qtsimplewaveformwidget.h"
20#include "waveform/widgets/glslwaveformwidget.h"20#include "waveform/widgets/glslwaveformwidget.h"
21#include "waveform/widgets/glvsynctestwidget.h"
21#include "waveform/widgets/waveformwidgetabstract.h"22#include "waveform/widgets/waveformwidgetabstract.h"
22#include "widget/wwaveformviewer.h"23#include "widget/wwaveformviewer.h"
24#include "waveform/vsyncthread.h"
25#include "util/cmdlineargs.h"
26
27#include "util/performancetimer.h"
23#include "util/timer.h"28#include "util/timer.h"
2429
25///////////////////////////////////////////30///////////////////////////////////////////
@@ -31,6 +36,12 @@
3136
32///////////////////////////////////////////37///////////////////////////////////////////
3338
39WaveformWidgetHolder::WaveformWidgetHolder()
40 : m_waveformWidget(NULL),
41 m_waveformViewer(NULL),
42 m_visualNodeCache(QDomNode()) {
43}
44
34WaveformWidgetHolder::WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget,45WaveformWidgetHolder::WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget,
35 WWaveformViewer* waveformViewer,46 WWaveformViewer* waveformViewer,
36 const QDomNode& visualNodeCache)47 const QDomNode& visualNodeCache)
@@ -51,8 +62,8 @@
51 m_overviewNormalized(false),62 m_overviewNormalized(false),
52 m_openGLAvailable(false),63 m_openGLAvailable(false),
53 m_openGLShaderAvailable(false),64 m_openGLShaderAvailable(false),
54 m_time(new QTime()),65 m_vsyncThread(NULL),
55 m_lastFrameTime(0),66 m_frameCnt(0),
56 m_actualFrameRate(0) {67 m_actualFrameRate(0) {
5768
58 m_visualGain[All] = 1.5;69 m_visualGain[All] = 1.5;
@@ -129,17 +140,20 @@
129 }140 }
130141
131 evaluateWidgets();142 evaluateWidgets();
132 start();143 m_time.start();
133}144}
134145
135WaveformWidgetFactory::~WaveformWidgetFactory() {146WaveformWidgetFactory::~WaveformWidgetFactory() {
136 delete m_time;147 if (m_vsyncThread) {
148 delete m_vsyncThread;
149 }
137}150}
138151
139bool WaveformWidgetFactory::setConfig(ConfigObject<ConfigValue> *config){152bool WaveformWidgetFactory::setConfig(ConfigObject<ConfigValue> *config) {
140 m_config = config;153 m_config = config;
141 if (!m_config)154 if (!m_config) {
142 return false;155 return false;
156 }
143157
144 bool ok = false;158 bool ok = false;
145159
@@ -150,6 +164,9 @@
150 m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));164 m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));
151 }165 }
152166
167 int vsync = m_config->getValueString(ConfigKey("[Waveform]","VSync"),"0").toInt();
168 setVSyncType(vsync);
169
153 int defaultZoom = m_config->getValueString(ConfigKey("[Waveform]","DefaultZoom")).toInt(&ok);170 int defaultZoom = m_config->getValueString(ConfigKey("[Waveform]","DefaultZoom")).toInt(&ok);
154 if (ok) {171 if (ok) {
155 setDefaultZoom(defaultZoom);172 setDefaultZoom(defaultZoom);
@@ -192,25 +209,8 @@
192 return true;209 return true;
193}210}
194211
195void WaveformWidgetFactory::start() {
196 //qDebug() << "WaveformWidgetFactory::start";
197 killTimer(m_mainTimerId);
198 m_mainTimerId = startTimer(1000.0/double(m_frameRate));
199}
200
201void WaveformWidgetFactory::stop() {
202 killTimer(m_mainTimerId);
203 m_mainTimerId = -1;
204}
205
206void WaveformWidgetFactory::timerEvent(QTimerEvent *timerEvent) {
207 if (timerEvent->timerId() == m_mainTimerId) {
208 refresh();
209 }
210}
211
212void WaveformWidgetFactory::destroyWidgets() {212void WaveformWidgetFactory::destroyWidgets() {
213 for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) {213 for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
214 WaveformWidgetAbstract* pWidget = m_waveformWidgetHolders[i].m_waveformWidget;;214 WaveformWidgetAbstract* pWidget = m_waveformWidgetHolders[i].m_waveformWidget;;
215 m_waveformWidgetHolders[i].m_waveformWidget = NULL;215 m_waveformWidgetHolders[i].m_waveformWidget = NULL;
216 delete pWidget;216 delete pWidget;
@@ -247,6 +247,7 @@
247 }247 }
248248
249 viewer->setZoom(m_defaultZoom);249 viewer->setZoom(m_defaultZoom);
250 viewer->update();
250251
251 qDebug() << "WaveformWidgetFactory::setWaveformWidget - waveform widget added in factory, index" << index;252 qDebug() << "WaveformWidgetFactory::setWaveformWidget - waveform widget added in factory, index" << index;
252253
@@ -254,11 +255,25 @@
254}255}
255256
256void WaveformWidgetFactory::setFrameRate(int frameRate) {257void WaveformWidgetFactory::setFrameRate(int frameRate) {
257 m_frameRate = math_min(60, math_max(10, frameRate));258 m_frameRate = math_min(120, math_max(1, frameRate));
258 if (m_config) {259 if (m_config) {
259 m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));260 m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate));
260 }261 }
261 start();262 m_vsyncThread->setUsSyncTime(1000000/m_frameRate);
263}
264
265
266void WaveformWidgetFactory::setVSyncType(int type) {
267 if (m_config) {
268 m_config->set(ConfigKey("[Waveform]","VSync"), ConfigValue((int)type));
269 }
270
271 m_vSyncType = type;
272 m_vsyncThread->setVSyncType(type);
273}
274
275int WaveformWidgetFactory::getVSyncType() {
276 return m_vSyncType;
262}277}
263278
264bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type) {279bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type) {
@@ -266,7 +281,7 @@
266 return true;281 return true;
267282
268 // check if type is acceptable283 // check if type is acceptable
269 for (unsigned int i = 0; i < m_waveformWidgetHandles.size(); i++) {284 for (int i = 0; i < m_waveformWidgetHandles.size(); i++) {
270 WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i];285 WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i];
271 if (handle.m_type == type) {286 if (handle.m_type == type) {
272 // type is acceptable287 // type is acceptable
@@ -307,7 +322,7 @@
307 //qDebug() << "recreate start";322 //qDebug() << "recreate start";
308323
309 //re-create/setup all waveform widgets324 //re-create/setup all waveform widgets
310 for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) {325 for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
311 WaveformWidgetHolder& holder = m_waveformWidgetHolders[i];326 WaveformWidgetHolder& holder = m_waveformWidgetHolders[i];
312 WaveformWidgetAbstract* previousWidget = holder.m_waveformWidget;327 WaveformWidgetAbstract* previousWidget = holder.m_waveformWidget;
313 TrackPointer pTrack = previousWidget->getTrackInfo();328 TrackPointer pTrack = previousWidget->getTrackInfo();
@@ -325,6 +340,8 @@
325 //viewer->resize(viewer->size());340 //viewer->resize(viewer->size());
326 widget->resize(viewer->width(), viewer->height());341 widget->resize(viewer->width(), viewer->height());
327 widget->setTrack(pTrack);342 widget->setTrack(pTrack);
343 widget->getWidget()->show();
344 viewer->update();
328 }345 }
329346
330 m_skipRender = false;347 m_skipRender = false;
@@ -339,7 +356,7 @@
339 m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom));356 m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom));
340 }357 }
341358
342 for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) {359 for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
343 m_waveformWidgetHolders[i].m_waveformViewer->setZoom(m_defaultZoom);360 m_waveformWidgetHolders[i].m_waveformViewer->setZoom(m_defaultZoom);
344 }361 }
345}362}
@@ -355,7 +372,7 @@
355 }372 }
356373
357 int refZoom = m_waveformWidgetHolders[0].m_waveformWidget->getZoomFactor();374 int refZoom = m_waveformWidgetHolders[0].m_waveformWidget->getZoomFactor();
358 for (unsigned int i = 1; i < m_waveformWidgetHolders.size(); i++) {375 for (int i = 1; i < m_waveformWidgetHolders.size(); i++) {
359 m_waveformWidgetHolders[i].m_waveformViewer->setZoom(refZoom);376 m_waveformWidgetHolders[i].m_waveformViewer->setZoom(refZoom);
360 }377 }
361}378}
@@ -390,29 +407,67 @@
390}407}
391408
392void WaveformWidgetFactory::refresh() {409void WaveformWidgetFactory::refresh() {
393 if (m_skipRender)
394 return;
395
396 ScopedTimer t(QString("WaveformWidgetFactory::refresh() %1waveforms")410 ScopedTimer t(QString("WaveformWidgetFactory::refresh() %1waveforms")
397 .arg(m_waveformWidgetHolders.size()));411 .arg(m_waveformWidgetHolders.size()));
398412
399 for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++)413 int paintersSetupTime0 = 0;
400 m_waveformWidgetHolders[i].m_waveformWidget->preRender();414 int paintersSetupTime1 = 0;
401415
402 for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++)416 if (!m_skipRender) {
403 m_waveformWidgetHolders[i].m_waveformWidget->render();417 if (m_type) { // no regular updates for an empty waveform
404418 // next rendered frame is displayed after next buffer swap and than after VSync
405 for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++)419 for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
406 m_waveformWidgetHolders[i].m_waveformWidget->postRender();420 // Calculate play position for the new Frame in following run
407421 m_waveformWidgetHolders[i].m_waveformWidget->preRender(m_vsyncThread);
408 // Notify all other waveform-like widgets (e.g. WSpinny's) that they should422 }
409 // update.423 //qDebug() << "prerender" << m_vsyncThread->elapsed();
410 emit(waveformUpdateTick());424
411425 // It may happen that there is an artificially delayed due to
412 m_lastFrameTime = m_time->restart();426 // anti tearing driver settings
413 if (m_lastFrameTime && m_lastFrameTime <= 1000) {427 // all render commands are delayed until the swap from the previous run is executed
414 m_actualFrameRate = 1000.0/(double)(m_lastFrameTime);428 for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
415 }429 (void)m_waveformWidgetHolders[i].m_waveformWidget->render();
430 // qDebug() << "render" << i << m_vsyncThread->elapsed();
431 }
432 }
433
434 // Notify all other waveform-like widgets (e.g. WSpinny's) that they should
435 // update.
436 //int t1 = m_vsyncThread->elapsed();
437 emit(waveformUpdateTick());
438 //qDebug() << "emit" << m_vsyncThread->elapsed() - t1;
439
440 m_frameCnt += 1.0;
441 int timeCnt = m_time.elapsed();
442 if (timeCnt > 1000) {
443 m_time.start();
444 m_frameCnt = m_frameCnt * 1000 / timeCnt; // latency correction
445 emit(waveformMeasured(m_frameCnt, m_vsyncThread->rtErrorCnt()));
446 m_frameCnt = 0.0;
447 }
448 }
449 //qDebug() << "refresh end" << m_vsyncThread->elapsed();
450 m_vsyncThread->vsyncSlotFinished();
451}
452
453void WaveformWidgetFactory::postRefresh() {
454 // Do this in an extra slot to be sure to hit the desired interval
455 if (!m_skipRender) {
456 if (m_type) { // no regular updates for an empty waveform
457 // Show rendered buffer from last refresh() run
458 //qDebug() << "postRefresh start" << m_vsyncThread->elapsed();
459 for (int i = 0; i < m_waveformWidgetHolders.size(); i++) {
460 QGLWidget* glw = dynamic_cast<QGLWidget*>(
461 m_waveformWidgetHolders[i].m_waveformWidget->getWidget());
462 if (glw) {
463 m_vsyncThread->postRender(glw, i);
464 }
465 //qDebug() << "postRefresh x" << m_vsyncThread->elapsed();
466 }
467 }
468 }
469 //qDebug() << "postRefresh end" << m_vsyncThread->elapsed();
470 m_vsyncThread->vsyncSlotFinished();
416}471}
417472
418WaveformWidgetType::Type WaveformWidgetFactory::autoChooseWidgetType() const {473WaveformWidgetType::Type WaveformWidgetFactory::autoChooseWidgetType() const {
@@ -435,12 +490,14 @@
435 QString widgetName;490 QString widgetName;
436 bool useOpenGl;491 bool useOpenGl;
437 bool useOpenGLShaders;492 bool useOpenGLShaders;
493 bool developerOnly;
438494
439 switch(type) {495 switch(type) {
440 case WaveformWidgetType::EmptyWaveform:496 case WaveformWidgetType::EmptyWaveform:
441 widgetName = EmptyWaveformWidget::getWaveformWidgetName();497 widgetName = EmptyWaveformWidget::getWaveformWidgetName();
442 useOpenGl = EmptyWaveformWidget::useOpenGl();498 useOpenGl = EmptyWaveformWidget::useOpenGl();
443 useOpenGLShaders = EmptyWaveformWidget::useOpenGLShaders();499 useOpenGLShaders = EmptyWaveformWidget::useOpenGLShaders();
500 developerOnly = EmptyWaveformWidget::developerOnly();
444 break;501 break;
445 case WaveformWidgetType::SoftwareSimpleWaveform:502 case WaveformWidgetType::SoftwareSimpleWaveform:
446 continue; // //TODO(vrince):503 continue; // //TODO(vrince):
@@ -448,37 +505,52 @@
448 widgetName = SoftwareWaveformWidget::getWaveformWidgetName();505 widgetName = SoftwareWaveformWidget::getWaveformWidgetName();
449 useOpenGl = SoftwareWaveformWidget::useOpenGl();506 useOpenGl = SoftwareWaveformWidget::useOpenGl();
450 useOpenGLShaders = SoftwareWaveformWidget::useOpenGLShaders();507 useOpenGLShaders = SoftwareWaveformWidget::useOpenGLShaders();
508 developerOnly = SoftwareWaveformWidget::developerOnly();
451 break;509 break;
452 case WaveformWidgetType::HSVWaveform:510 case WaveformWidgetType::HSVWaveform:
453 widgetName = HSVWaveformWidget::getWaveformWidgetName();511 widgetName = HSVWaveformWidget::getWaveformWidgetName();
454 useOpenGl = HSVWaveformWidget::useOpenGl();512 useOpenGl = HSVWaveformWidget::useOpenGl();
455 useOpenGLShaders = HSVWaveformWidget::useOpenGLShaders();513 useOpenGLShaders = HSVWaveformWidget::useOpenGLShaders();
514 developerOnly = HSVWaveformWidget::developerOnly();
456 break;515 break;
457 case WaveformWidgetType::QtSimpleWaveform:516 case WaveformWidgetType::QtSimpleWaveform:
458 widgetName = QtSimpleWaveformWidget::getWaveformWidgetName();517 widgetName = QtSimpleWaveformWidget::getWaveformWidgetName();
459 useOpenGl = QtSimpleWaveformWidget::useOpenGl();518 useOpenGl = QtSimpleWaveformWidget::useOpenGl();
460 useOpenGLShaders = QtSimpleWaveformWidget::useOpenGLShaders();519 useOpenGLShaders = QtSimpleWaveformWidget::useOpenGLShaders();
520 developerOnly = QtSimpleWaveformWidget::developerOnly();
461 break;521 break;
462 case WaveformWidgetType::QtWaveform:522 case WaveformWidgetType::QtWaveform:
463 widgetName = QtWaveformWidget::getWaveformWidgetName();523 widgetName = QtWaveformWidget::getWaveformWidgetName();
464 useOpenGl = QtWaveformWidget::useOpenGl();524 useOpenGl = QtWaveformWidget::useOpenGl();
465 useOpenGLShaders = QtWaveformWidget::useOpenGLShaders();525 useOpenGLShaders = QtWaveformWidget::useOpenGLShaders();
526 developerOnly = QtWaveformWidget::developerOnly();
466 break;527 break;
467 case WaveformWidgetType::GLSimpleWaveform:528 case WaveformWidgetType::GLSimpleWaveform:
468 widgetName = GLSimpleWaveformWidget::getWaveformWidgetName();529 widgetName = GLSimpleWaveformWidget::getWaveformWidgetName();
469 useOpenGl = GLSimpleWaveformWidget::useOpenGl();530 useOpenGl = GLSimpleWaveformWidget::useOpenGl();
470 useOpenGLShaders = GLSimpleWaveformWidget::useOpenGLShaders();531 useOpenGLShaders = GLSimpleWaveformWidget::useOpenGLShaders();
532 developerOnly = GLSimpleWaveformWidget::developerOnly();
471 break;533 break;
472 case WaveformWidgetType::GLWaveform:534 case WaveformWidgetType::GLWaveform:
473 widgetName = GLWaveformWidget::getWaveformWidgetName();535 widgetName = GLWaveformWidget::getWaveformWidgetName();
474 useOpenGl = GLWaveformWidget::useOpenGl();536 useOpenGl = GLWaveformWidget::useOpenGl();
475 useOpenGLShaders = GLWaveformWidget::useOpenGLShaders();537 useOpenGLShaders = GLWaveformWidget::useOpenGLShaders();
538 developerOnly = GLWaveformWidget::developerOnly();
476 break;539 break;
477 case WaveformWidgetType::GLSLWaveform:540 case WaveformWidgetType::GLSLWaveform:
478 widgetName = GLSLWaveformWidget::getWaveformWidgetName();541 widgetName = GLSLWaveformWidget::getWaveformWidgetName();
479 useOpenGl = GLSLWaveformWidget::useOpenGl();542 useOpenGl = GLSLWaveformWidget::useOpenGl();
480 useOpenGLShaders = GLSLWaveformWidget::useOpenGLShaders();543 useOpenGLShaders = GLSLWaveformWidget::useOpenGLShaders();
481 break;544 developerOnly = GLSLWaveformWidget::developerOnly();
545 break;
546 case WaveformWidgetType::GLVSyncTest:
547 widgetName = GLVSyncTestWidget::getWaveformWidgetName();
548 useOpenGl = GLVSyncTestWidget::useOpenGl();
549 useOpenGLShaders = GLVSyncTestWidget::useOpenGLShaders();
550 developerOnly = GLVSyncTestWidget::developerOnly();
551 break;
552 default:
553 continue;
482 }554 }
483555
484 if (useOpenGLShaders) {556 if (useOpenGLShaders) {
@@ -499,6 +571,12 @@
499 handle.m_active = false;571 handle.m_active = false;
500 continue;572 continue;
501 }573 }
574
575 if (developerOnly && !CmdlineArgs::Instance().getDeveloper()) {
576 handle.m_active = false;
577 continue;
578 }
579
502 m_waveformWidgetHandles.push_back(handle);580 m_waveformWidgetHandles.push_back(handle);
503 }581 }
504}582}
@@ -529,6 +607,9 @@
529 case WaveformWidgetType::GLSLWaveform:607 case WaveformWidgetType::GLSLWaveform:
530 widget = new GLSLWaveformWidget(viewer->getGroup(), viewer);608 widget = new GLSLWaveformWidget(viewer->getGroup(), viewer);
531 break;609 break;
610 case WaveformWidgetType::GLVSyncTest:
611 widget = new GLVSyncTestWidget(viewer->getGroup(), viewer);
612 break;
532 default:613 default:
533 //case WaveformWidgetType::SoftwareSimpleWaveform: TODO: (vrince)614 //case WaveformWidgetType::SoftwareSimpleWaveform: TODO: (vrince)
534 //case WaveformWidgetType::EmptyWaveform:615 //case WaveformWidgetType::EmptyWaveform:
@@ -552,8 +633,32 @@
552}633}
553634
554int WaveformWidgetFactory::findIndexOf(WWaveformViewer* viewer) const {635int WaveformWidgetFactory::findIndexOf(WWaveformViewer* viewer) const {
555 for (int i = 0; i < (int)m_waveformWidgetHolders.size(); i++)636 for (int i = 0; i < (int)m_waveformWidgetHolders.size(); i++) {
556 if (m_waveformWidgetHolders[i].m_waveformViewer == viewer)637 if (m_waveformWidgetHolders[i].m_waveformViewer == viewer) {
557 return i;638 return i;
639 }
640 }
558 return -1;641 return -1;
559}642}
643
644void WaveformWidgetFactory::startVSync(QWidget *parent) {
645 if (m_vsyncThread) {
646 disconnect(m_vsyncThread, SIGNAL(vsync1()), this, SLOT(refresh()));
647 disconnect(m_vsyncThread, SIGNAL(vsync2()), this, SLOT(postRefresh()));
648 delete m_vsyncThread;
649 }
650 m_vsyncThread = new VSyncThread(parent);
651 m_vsyncThread->start();
652
653 connect(m_vsyncThread, SIGNAL(vsync1()),
654 this, SLOT(refresh()));
655 connect(m_vsyncThread, SIGNAL(vsync2()),
656 this, SLOT(postRefresh()));
657
658}
659
660void WaveformWidgetFactory::getAvailableVSyncTypes(QList<QPair<int, QString > >* pList) {
661 m_vsyncThread->getAvailableVSyncTypes(pList);
662}
663
664
560665
=== modified file 'mixxx/src/waveform/waveformwidgetfactory.h'
--- mixxx/src/waveform/waveformwidgetfactory.h 2012-05-30 18:26:44 +0000
+++ mixxx/src/waveform/waveformwidgetfactory.h 2013-05-01 22:08:27 +0000
@@ -8,14 +8,15 @@
8#include "waveform/waveform.h"8#include "waveform/waveform.h"
99
10#include <QObject>10#include <QObject>
1111#include <QTime>
12#include <vector>12#include <QVector>
1313
14class WWaveformViewer;14class WWaveformViewer;
15class WaveformWidgetAbstract;15class WaveformWidgetAbstract;
16class ControlObjectThreadMain;16class ControlObjectThreadMain;
17class QTimer;17class QTimer;
18class QTime;18class VSyncThread;
19
1920
20class WaveformWidgetAbstractHandle {21class WaveformWidgetAbstractHandle {
21 public:22 public:
@@ -34,7 +35,9 @@
34};35};
3536
36class WaveformWidgetHolder {37class WaveformWidgetHolder {
37private:38 public:
39 WaveformWidgetHolder();
40 private:
38 WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget,41 WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget,
39 WWaveformViewer* waveformViewer,42 WWaveformViewer* waveformViewer,
40 const QDomNode& visualNodeCache);43 const QDomNode& visualNodeCache);
@@ -62,7 +65,7 @@
6265
63 void setFrameRate( int frameRate);66 void setFrameRate( int frameRate);
64 int getFrameRate() const { return m_frameRate;}67 int getFrameRate() const { return m_frameRate;}
65 double getActualFrameRate() const { return m_actualFrameRate;}68// bool getVSync() const { return m_vSyncType;}
6669
67 bool isOpenGLAvailable() const { return m_openGLAvailable;}70 bool isOpenGLAvailable() const { return m_openGLAvailable;}
68 QString getOpenGLVersion() const { return m_openGLVersion;}71 QString getOpenGLVersion() const { return m_openGLVersion;}
@@ -85,22 +88,21 @@
85 void setOverviewNormalized(bool normalize);88 void setOverviewNormalized(bool normalize);
86 int isOverviewNormalized() const { return m_overviewNormalized;}89 int isOverviewNormalized() const { return m_overviewNormalized;}
8790
88 const std::vector<WaveformWidgetAbstractHandle> getAvailableTypes() const { return m_waveformWidgetHandles;}91 const QVector<WaveformWidgetAbstractHandle> getAvailableTypes() const { return m_waveformWidgetHandles;}
92 void getAvailableVSyncTypes(QList<QPair<int, QString > >* list);
89 void destroyWidgets();93 void destroyWidgets();
9094
91 void addTimerListener(QWidget* pWidget);95 void addTimerListener(QWidget* pWidget);
9296
93 public slots:97 void startVSync(QWidget *parent);
94 void start();98 void setVSyncType(int vsType);
95 void stop();99 int getVSyncType();
96100
97 void notifyZoomChange(WWaveformViewer *viewer);101 void notifyZoomChange(WWaveformViewer *viewer);
98102
99 signals:103 signals:
100 void waveformUpdateTick();104 void waveformUpdateTick();
101105 void waveformMeasured(float frameRate, int rtErrorCnt);
102 protected:
103 void timerEvent(QTimerEvent *timerEvent);
104106
105 protected:107 protected:
106 WaveformWidgetFactory();108 WaveformWidgetFactory();
@@ -110,6 +112,7 @@
110112
111 private slots:113 private slots:
112 void refresh();114 void refresh();
115 void postRefresh();
113116
114 private:117 private:
115 WaveformWidgetType::Type autoChooseWidgetType() const;118 WaveformWidgetType::Type autoChooseWidgetType() const;
@@ -118,10 +121,11 @@
118 int findIndexOf( WWaveformViewer* viewer) const;121 int findIndexOf( WWaveformViewer* viewer) const;
119122
120 //All type of available widgets123 //All type of available widgets
121 std::vector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles;124
125 QVector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles;
122126
123 //Currently in use widgets/visual/node127 //Currently in use widgets/visual/node
124 std::vector<WaveformWidgetHolder> m_waveformWidgetHolders;128 QVector<WaveformWidgetHolder> m_waveformWidgetHolders;
125129
126 WaveformWidgetType::Type m_type;130 WaveformWidgetType::Type m_type;
127131
@@ -139,10 +143,17 @@
139 QString m_openGLVersion;143 QString m_openGLVersion;
140 bool m_openGLShaderAvailable;144 bool m_openGLShaderAvailable;
141145
146 VSyncThread* m_vsyncThread;
147
142 //Debug148 //Debug
143 QTime* m_time;149 QTime m_time;
144 int m_lastFrameTime;150 QTime m_delayTime;
151 float m_frameCnt;
152 int m_lastRenderDuration;
145 double m_actualFrameRate;153 double m_actualFrameRate;
154 double m_minimumFrameRate;
155 double m_maximumlFrameRate;
156 int m_vSyncType;
146};157};
147158
148#endif // WAVEFORMWIDGETFACTORY_H159#endif // WAVEFORMWIDGETFACTORY_H
149160
=== modified file 'mixxx/src/waveform/widgets/emptywaveformwidget.cpp'
--- mixxx/src/waveform/widgets/emptywaveformwidget.cpp 2012-09-19 21:04:53 +0000
+++ mixxx/src/waveform/widgets/emptywaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -25,6 +25,12 @@
25}25}
2626
27void EmptyWaveformWidget::paintEvent(QPaintEvent* event) {27void EmptyWaveformWidget::paintEvent(QPaintEvent* event) {
28 // Only render if Qt thinks it is required
28 QPainter painter(this);29 QPainter painter(this);
29 draw(&painter,event);30 draw(&painter,event);
30}31}
32
33int EmptyWaveformWidget::render() {
34 // skip update every frame
35 return 0;
36}
3137
=== modified file 'mixxx/src/waveform/widgets/emptywaveformwidget.h'
--- mixxx/src/waveform/widgets/emptywaveformwidget.h 2012-09-19 21:04:53 +0000
+++ mixxx/src/waveform/widgets/emptywaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -18,13 +18,14 @@
18 static inline QString getWaveformWidgetName() { return tr("Empty"); }18 static inline QString getWaveformWidgetName() { return tr("Empty"); }
19 static inline bool useOpenGl() { return false; }19 static inline bool useOpenGl() { return false; }
20 static inline bool useOpenGLShaders() { return false; }20 static inline bool useOpenGLShaders() { return false; }
21 static inline bool developerOnly() { return false; }
2122
22 protected:23 protected:
23 virtual void castToQWidget();24 virtual void castToQWidget();
24 virtual void paintEvent(QPaintEvent* event);25 virtual void paintEvent(QPaintEvent* event);
26 virtual int render();
2527
26 private:28 private:
27 EmptyWaveformWidget() {}
28 EmptyWaveformWidget(const char* group, QWidget* parent);29 EmptyWaveformWidget(const char* group, QWidget* parent);
29 friend class WaveformWidgetFactory;30 friend class WaveformWidgetFactory;
30};31};
3132
=== modified file 'mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp'
--- mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp 2013-01-04 20:29:33 +0000
+++ mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -13,6 +13,8 @@
13#include "waveform/renderers/waveformrendererendoftrack.h"13#include "waveform/renderers/waveformrendererendoftrack.h"
14#include "waveform/renderers/waveformrenderbeat.h"14#include "waveform/renderers/waveformrenderbeat.h"
1515
16#include "util/performancetimer.h"
17
16GLSimpleWaveformWidget::GLSimpleWaveformWidget( const char* group, QWidget* parent)18GLSimpleWaveformWidget::GLSimpleWaveformWidget( const char* group, QWidget* parent)
17 : QGLWidget(parent, SharedGLContext::getWidget()),19 : QGLWidget(parent, SharedGLContext::getWidget()),
18 WaveformWidgetAbstract(group) {20 WaveformWidgetAbstract(group) {
@@ -49,11 +51,24 @@
49}51}
5052
51void GLSimpleWaveformWidget::paintEvent( QPaintEvent* event) {53void GLSimpleWaveformWidget::paintEvent( QPaintEvent* event) {
52 if (QGLContext::currentContext() != context()) {54 Q_UNUSED(event);
53 makeCurrent();55}
54 }56
57int GLSimpleWaveformWidget::render() {
58 PerformanceTimer timer;
59 int t1;
60 //int t2, t3;
61 timer.start();
62 // QPainter makes QGLContext::currentContext() == context()
63 // this may delayed until previous buffer swap finished
55 QPainter painter(this);64 QPainter painter(this);
56 draw(&painter,event);65 t1 = timer.restart();
66 draw(&painter, NULL);
67 //t2 = timer.restart();
68 //glFinish();
69 //t3 = timer.restart();
70 //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3;
71 return t1 / 1000; // return timer for painter setup
57}72}
5873
59void GLSimpleWaveformWidget::postRender() {74void GLSimpleWaveformWidget::postRender() {
6075
=== modified file 'mixxx/src/waveform/widgets/glsimplewaveformwidget.h'
--- mixxx/src/waveform/widgets/glsimplewaveformwidget.h 2012-09-19 21:04:53 +0000
+++ mixxx/src/waveform/widgets/glsimplewaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -11,19 +11,20 @@
11 GLSimpleWaveformWidget(const char* group, QWidget* parent);11 GLSimpleWaveformWidget(const char* group, QWidget* parent);
12 virtual ~GLSimpleWaveformWidget();12 virtual ~GLSimpleWaveformWidget();
1313
14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform;}14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform; }
1515
16 static inline QString getWaveformWidgetName() { return tr("Simple");}16 static inline QString getWaveformWidgetName() { return tr("Simple"); }
17 static inline bool useOpenGl() { return true;}17 static inline bool useOpenGl() { return true; }
18 static inline bool useOpenGLShaders() { return false;}18 static inline bool useOpenGLShaders() { return false; }
19 static inline bool developerOnly() { return false; }
1920
20 protected:21 protected:
21 virtual void castToQWidget();22 virtual void castToQWidget();
22 virtual void paintEvent(QPaintEvent* event);23 virtual void paintEvent(QPaintEvent* event);
23 virtual void postRender();24 virtual void postRender();
25 virtual int render();
2426
25 private:27 private:
26 GLSimpleWaveformWidget() {}
27 friend class WaveformWidgetFactory;28 friend class WaveformWidgetFactory;
28};29};
29#endif // GLSIMPLEWAVEFORMWIDGET_H30#endif // GLSIMPLEWAVEFORMWIDGET_H
3031
=== modified file 'mixxx/src/waveform/widgets/glslwaveformwidget.cpp'
--- mixxx/src/waveform/widgets/glslwaveformwidget.cpp 2013-01-04 20:29:33 +0000
+++ mixxx/src/waveform/widgets/glslwaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -13,6 +13,8 @@
13#include "waveform/renderers/waveformrenderbeat.h"13#include "waveform/renderers/waveformrenderbeat.h"
14#include "sharedglcontext.h"14#include "sharedglcontext.h"
1515
16#include "util/performancetimer.h"
17
16GLSLWaveformWidget::GLSLWaveformWidget( const char* group, QWidget* parent)18GLSLWaveformWidget::GLSLWaveformWidget( const char* group, QWidget* parent)
17 : QGLWidget(parent, SharedGLContext::getWidget()),19 : QGLWidget(parent, SharedGLContext::getWidget()),
18 WaveformWidgetAbstract(group) {20 WaveformWidgetAbstract(group) {
@@ -48,10 +50,24 @@
48}50}
4951
50void GLSLWaveformWidget::paintEvent( QPaintEvent* event) {52void GLSLWaveformWidget::paintEvent( QPaintEvent* event) {
51 makeCurrent();53 Q_UNUSED(event);
54}
55
56int GLSLWaveformWidget::render() {
57 PerformanceTimer timer;
58 int t1;
59 //int t2, t3;
60 timer.start();
61 // QPainter makes QGLContext::currentContext() == context()
62 // this may delayed until previous buffer swap finished
52 QPainter painter(this);63 QPainter painter(this);
53 draw(&painter,event);64 t1 = timer.restart();
54 QGLWidget::swapBuffers();65 draw(&painter, NULL);
66 //t2 = timer.restart();
67 //glFinish();
68 //t3 = timer.restart();
69 //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3;
70 return t1 / 1000; // return timer for painter setup
55}71}
5672
57void GLSLWaveformWidget::resize( int width, int height) {73void GLSLWaveformWidget::resize( int width, int height) {
@@ -67,3 +83,7 @@
67 signalRenderer_->loadShaders();83 signalRenderer_->loadShaders();
68 }84 }
69}85}
86
87void GLSLWaveformWidget::postRender() {
88 swapBuffers();
89}
7090
=== modified file 'mixxx/src/waveform/widgets/glslwaveformwidget.h'
--- mixxx/src/waveform/widgets/glslwaveformwidget.h 2012-12-06 06:35:21 +0000
+++ mixxx/src/waveform/widgets/glslwaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -13,11 +13,12 @@
13 GLSLWaveformWidget(const char* group, QWidget* parent);13 GLSLWaveformWidget(const char* group, QWidget* parent);
14 virtual ~GLSLWaveformWidget();14 virtual ~GLSLWaveformWidget();
1515
16 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSLWaveform;}16 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSLWaveform; }
1717
18 static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("experimental");}18 static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("experimental"); }
19 static inline bool useOpenGl() { return true;}19 static inline bool useOpenGl() { return true; }
20 static inline bool useOpenGLShaders() { return true;}20 static inline bool useOpenGLShaders() { return true; }
21 static inline bool developerOnly() { return false; }
2122
22 virtual void resize(int width, int height);23 virtual void resize(int width, int height);
2324
@@ -25,11 +26,12 @@
25 virtual void castToQWidget();26 virtual void castToQWidget();
26 virtual void paintEvent(QPaintEvent* event);27 virtual void paintEvent(QPaintEvent* event);
27 virtual void mouseDoubleClickEvent(QMouseEvent *);28 virtual void mouseDoubleClickEvent(QMouseEvent *);
29 virtual void postRender();
30 virtual int render();
2831
29 private:32 private:
30 GLSLWaveformRendererSignal* signalRenderer_;33 GLSLWaveformRendererSignal* signalRenderer_;
3134
32 GLSLWaveformWidget() {}
33 friend class WaveformWidgetFactory;35 friend class WaveformWidgetFactory;
34};36};
3537
3638
=== added file 'mixxx/src/waveform/widgets/glvsynctestwidget.cpp'
--- mixxx/src/waveform/widgets/glvsynctestwidget.cpp 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/widgets/glvsynctestwidget.cpp 2013-05-01 22:08:27 +0000
@@ -0,0 +1,75 @@
1#include "glvsynctestwidget.h"
2
3#include <QPainter>
4
5#include "sharedglcontext.h"
6#include "waveform/renderers/waveformwidgetrenderer.h"
7#include "waveform/renderers/waveformrenderbackground.h"
8#include "waveform/renderers/glwaveformrenderersimplesignal.h"
9#include "waveform/renderers/glvsynctestrenderer.h"
10#include "waveform/renderers/waveformrendererpreroll.h"
11#include "waveform/renderers/waveformrendermark.h"
12#include "waveform/renderers/waveformrendermarkrange.h"
13#include "waveform/renderers/waveformrendererendoftrack.h"
14#include "waveform/renderers/waveformrenderbeat.h"
15
16#include "util/performancetimer.h"
17
18GLVSyncTestWidget::GLVSyncTestWidget( const char* group, QWidget* parent)
19 : QGLWidget(parent, SharedGLContext::getWidget()),
20 WaveformWidgetAbstract(group) {
21
22// addRenderer<WaveformRenderBackground>(); // 172 µs
23// addRenderer<WaveformRendererEndOfTrack>(); // 677 µs 1145 µs (active)
24// addRenderer<WaveformRendererPreroll>(); // 652 µs 2034 µs (active)
25// addRenderer<WaveformRenderMarkRange>(); // 793 µs
26 addRenderer<GLVSyncTestRenderer>(); // 841 µs // 2271 µs
27// addRenderer<WaveformRenderMark>(); // 711 µs
28// addRenderer<WaveformRenderBeat>(); // 1183 µs
29
30 setAttribute(Qt::WA_NoSystemBackground);
31 setAttribute(Qt::WA_OpaquePaintEvent);
32
33 setAutoBufferSwap(false);
34
35 if (QGLContext::currentContext() != context()) {
36 makeCurrent();
37 }
38 m_initSuccess = init();
39 qDebug() << "GLVSyncTestWidget.isSharing() =" << isSharing();
40}
41
42GLVSyncTestWidget::~GLVSyncTestWidget(){
43 if (QGLContext::currentContext() != context()) {
44 makeCurrent();
45 }
46}
47
48void GLVSyncTestWidget::castToQWidget() {
49 m_widget = static_cast<QWidget*>(static_cast<QGLWidget*>(this));
50}
51
52void GLVSyncTestWidget::paintEvent( QPaintEvent* event) {
53 Q_UNUSED(event);
54}
55
56int GLVSyncTestWidget::render() {
57 PerformanceTimer timer;
58 int t1;
59 //int t2, t3;
60 timer.start();
61 // QPainter makes QGLContext::currentContext() == context()
62 // this may delayed until previous buffer swap finished
63 QPainter painter(this);
64 t1 = timer.restart();
65 draw(&painter, NULL);
66 //t2 = timer.restart();
67 glFinish();
68 //t3 = timer.restart();
69 //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3;
70 return t1 / 1000; // return timer for painter setup
71}
72
73void GLVSyncTestWidget::postRender() {
74 QGLWidget::swapBuffers();
75}
076
=== added file 'mixxx/src/waveform/widgets/glvsynctestwidget.h'
--- mixxx/src/waveform/widgets/glvsynctestwidget.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/widgets/glvsynctestwidget.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,30 @@
1#ifndef GLVSYNCTESTWIDGET_H
2#define GLVSYNCTESTWIDGET_H
3
4#include <QGLWidget>
5
6#include "waveformwidgetabstract.h"
7
8class GLVSyncTestWidget : public QGLWidget, public WaveformWidgetAbstract {
9 Q_OBJECT
10 public:
11 GLVSyncTestWidget(const char* group, QWidget* parent);
12 virtual ~GLVSyncTestWidget();
13
14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLVSyncTest; }
15
16 static inline QString getWaveformWidgetName() { return tr("VSyncTest"); }
17 static inline bool useOpenGl() { return true; }
18 static inline bool useOpenGLShaders() { return false; }
19 static inline bool developerOnly() { return true; }
20
21 protected:
22 virtual void castToQWidget();
23 virtual void paintEvent(QPaintEvent* event);
24 virtual void postRender();
25 virtual int render();
26
27 private:
28 friend class WaveformWidgetFactory;
29};
30#endif // GLVSYNCTESTWIDGET_H
031
=== modified file 'mixxx/src/waveform/widgets/glwaveformwidget.cpp'
--- mixxx/src/waveform/widgets/glwaveformwidget.cpp 2013-01-04 20:29:33 +0000
+++ mixxx/src/waveform/widgets/glwaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -13,6 +13,7 @@
13#include "waveform/renderers/waveformrendererendoftrack.h"13#include "waveform/renderers/waveformrendererendoftrack.h"
14#include "waveform/renderers/waveformrenderbeat.h"14#include "waveform/renderers/waveformrenderbeat.h"
15#include "sharedglcontext.h"15#include "sharedglcontext.h"
16#include "util/performancetimer.h"
1617
17GLWaveformWidget::GLWaveformWidget( const char* group, QWidget* parent)18GLWaveformWidget::GLWaveformWidget( const char* group, QWidget* parent)
18 : QGLWidget(parent, SharedGLContext::getWidget()),19 : QGLWidget(parent, SharedGLContext::getWidget()),
@@ -48,11 +49,24 @@
48}49}
4950
50void GLWaveformWidget::paintEvent( QPaintEvent* event) {51void GLWaveformWidget::paintEvent( QPaintEvent* event) {
51 if (QGLContext::currentContext() != context()) {52 Q_UNUSED(event);
52 makeCurrent();53}
53 }54
55int GLWaveformWidget::render() {
56 PerformanceTimer timer;
57 int t1;
58 //int t2, t3;
59 timer.start();
60 // QPainter makes QGLContext::currentContext() == context()
61 // this may delayed until previous buffer swap finished
54 QPainter painter(this);62 QPainter painter(this);
55 draw(&painter, event);63 t1 = timer.restart();
64 draw(&painter, NULL);
65 //t2 = timer.restart();
66 // glFinish();
67 //t3 = timer.restart();
68 //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3;
69 return t1 / 1000; // return timer for painter setup
56}70}
5771
58void GLWaveformWidget::postRender() {72void GLWaveformWidget::postRender() {
5973
=== modified file 'mixxx/src/waveform/widgets/glwaveformwidget.h'
--- mixxx/src/waveform/widgets/glwaveformwidget.h 2012-12-06 06:35:21 +0000
+++ mixxx/src/waveform/widgets/glwaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -13,17 +13,18 @@
1313
14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLWaveform; }14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLWaveform; }
1515
16 static inline QString getWaveformWidgetName() { return tr("Filtered");}16 static inline QString getWaveformWidgetName() { return tr("Filtered"); }
17 static inline bool useOpenGl() { return true;}17 static inline bool useOpenGl() { return true; }
18 static inline bool useOpenGLShaders() { return false;}18 static inline bool useOpenGLShaders() { return false; }
19 static inline bool developerOnly() { return false; }
1920
20 protected:21 protected:
21 virtual void castToQWidget();22 virtual void castToQWidget();
22 virtual void paintEvent(QPaintEvent* event);23 virtual void paintEvent(QPaintEvent* event);
23 virtual void postRender();24 virtual void postRender();
25 virtual int render();
2426
25 private:27 private:
26 GLWaveformWidget() {}
27 friend class WaveformWidgetFactory;28 friend class WaveformWidgetFactory;
28};29};
2930
3031
=== added file 'mixxx/src/waveform/widgets/hsvwaveformwidget.cpp'
--- mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -0,0 +1,41 @@
1#include "hsvwaveformwidget.h"
2
3#include <QPainter>
4
5#include "waveform/renderers/waveformwidgetrenderer.h"
6#include "waveform/renderers/waveformrenderbackground.h"
7#include "waveform/renderers/waveformrendermark.h"
8#include "waveform/renderers/waveformrendermarkrange.h"
9#include "waveform/renderers/waveformrendererhsv.h"
10#include "waveform/renderers/waveformrendererpreroll.h"
11#include "waveform/renderers/waveformrendererendoftrack.h"
12#include "waveform/renderers/waveformrenderbeat.h"
13
14HSVWaveformWidget::HSVWaveformWidget( const char* group, QWidget* parent)
15 : QWidget(parent),
16 WaveformWidgetAbstract(group) {
17 addRenderer<WaveformRenderBackground>();
18 addRenderer<WaveformRendererEndOfTrack>();
19 addRenderer<WaveformRendererPreroll>();
20 addRenderer<WaveformRenderMarkRange>();
21 addRenderer<WaveformRendererHSV>();
22 addRenderer<WaveformRenderMark>();
23 addRenderer<WaveformRenderBeat>();
24
25 setAttribute(Qt::WA_NoSystemBackground);
26 setAttribute(Qt::WA_OpaquePaintEvent);
27
28 m_initSuccess = init();
29}
30
31HSVWaveformWidget::~HSVWaveformWidget() {
32}
33
34void HSVWaveformWidget::castToQWidget() {
35 m_widget = static_cast<QWidget*>(this);
36}
37
38void HSVWaveformWidget::paintEvent( QPaintEvent* event) {
39 QPainter painter(this);
40 draw(&painter,event);
41}
042
=== removed file 'mixxx/src/waveform/widgets/hsvwaveformwidget.cpp'
--- mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 2013-01-04 20:29:33 +0000
+++ mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
1#include "hsvwaveformwidget.h"
2
3#include <QPainter>
4
5#include "waveform/renderers/waveformwidgetrenderer.h"
6#include "waveform/renderers/waveformrenderbackground.h"
7#include "waveform/renderers/waveformrendermark.h"
8#include "waveform/renderers/waveformrendermarkrange.h"
9#include "waveform/renderers/waveformrendererhsv.h"
10#include "waveform/renderers/waveformrendererpreroll.h"
11#include "waveform/renderers/waveformrendererendoftrack.h"
12#include "waveform/renderers/waveformrenderbeat.h"
13
14HSVWaveformWidget::HSVWaveformWidget( const char* group, QWidget* parent)
15 : QWidget(parent),
16 WaveformWidgetAbstract(group) {
17 addRenderer<WaveformRenderBackground>();
18 addRenderer<WaveformRendererEndOfTrack>();
19 addRenderer<WaveformRendererPreroll>();
20 addRenderer<WaveformRenderMarkRange>();
21 addRenderer<WaveformRendererHSV>();
22 addRenderer<WaveformRenderBeat>();
23 addRenderer<WaveformRenderMark>();
24
25 setAttribute(Qt::WA_NoSystemBackground);
26 setAttribute(Qt::WA_OpaquePaintEvent);
27
28 m_initSuccess = init();
29}
30
31HSVWaveformWidget::~HSVWaveformWidget() {
32}
33
34void HSVWaveformWidget::castToQWidget() {
35 m_widget = static_cast<QWidget*>(this);
36}
37
38void HSVWaveformWidget::paintEvent( QPaintEvent* event) {
39 QPainter painter(this);
40 draw(&painter,event);
41}
420
=== added file 'mixxx/src/waveform/widgets/hsvwaveformwidget.h'
--- mixxx/src/waveform/widgets/hsvwaveformwidget.h 1970-01-01 00:00:00 +0000
+++ mixxx/src/waveform/widgets/hsvwaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -0,0 +1,29 @@
1#ifndef HSVWAVEFORMWIDGET_H
2#define HSVWAVEFORMWIDGET_H
3
4#include <QWidget>
5
6#include "waveformwidgetabstract.h"
7
8class HSVWaveformWidget : public QWidget, public WaveformWidgetAbstract {
9 Q_OBJECT
10 public:
11 virtual ~HSVWaveformWidget();
12
13 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::HSVWaveform; }
14
15 static inline QString getWaveformWidgetName() { return tr("HSV"); }
16 static inline bool useOpenGl() { return false; }
17 static inline bool useOpenGLShaders() { return false; }
18 static inline bool developerOnly() { return false; }
19
20 protected:
21 virtual void castToQWidget();
22 virtual void paintEvent(QPaintEvent* event);
23
24 private:
25 HSVWaveformWidget(const char* group, QWidget* parent);
26 friend class WaveformWidgetFactory;
27};
28
29#endif // HSVWAVEFORMWIDGET_H
030
=== removed file 'mixxx/src/waveform/widgets/hsvwaveformwidget.h'
--- mixxx/src/waveform/widgets/hsvwaveformwidget.h 2012-12-14 01:26:04 +0000
+++ mixxx/src/waveform/widgets/hsvwaveformwidget.h 1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
1#ifndef HSVWAVEFORMWIDGET_H
2#define HSVWAVEFORMWIDGET_H
3
4#include <QWidget>
5
6#include "waveformwidgetabstract.h"
7
8class HSVWaveformWidget : public QWidget, public WaveformWidgetAbstract {
9 Q_OBJECT
10 public:
11 virtual ~HSVWaveformWidget();
12
13 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::HSVWaveform;}
14
15 static inline QString getWaveformWidgetName() { return tr("HSV");}
16 static inline bool useOpenGl() { return false;}
17 static inline bool useOpenGLShaders() { return false;}
18
19 protected:
20 virtual void castToQWidget();
21 virtual void paintEvent(QPaintEvent* event);
22
23 private:
24 HSVWaveformWidget() {}
25 HSVWaveformWidget(const char* group, QWidget* parent);
26 friend class WaveformWidgetFactory;
27};
28
29#endif // HSVWAVEFORMWIDGET_H
300
=== modified file 'mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp'
--- mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp 2013-01-31 19:48:57 +0000
+++ mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -13,6 +13,8 @@
13#include "waveform/renderers/waveformrendererendoftrack.h"13#include "waveform/renderers/waveformrendererendoftrack.h"
14#include "waveform/renderers/waveformrenderbeat.h"14#include "waveform/renderers/waveformrenderbeat.h"
1515
16#include "util/performancetimer.h"
17
16QtSimpleWaveformWidget::QtSimpleWaveformWidget( const char* group, QWidget* parent)18QtSimpleWaveformWidget::QtSimpleWaveformWidget( const char* group, QWidget* parent)
17 : QGLWidget(parent, SharedGLContext::getWidget()),19 : QGLWidget(parent, SharedGLContext::getWidget()),
18 WaveformWidgetAbstract(group) {20 WaveformWidgetAbstract(group) {
@@ -49,11 +51,24 @@
49}51}
5052
51void QtSimpleWaveformWidget::paintEvent(QPaintEvent* event) {53void QtSimpleWaveformWidget::paintEvent(QPaintEvent* event) {
52 if (QGLContext::currentContext() != context()) {54 Q_UNUSED(event);
53 makeCurrent();55}
54 }56
57int QtSimpleWaveformWidget::render() {
58 PerformanceTimer timer;
59 int t1;
60 //int t2, t3;
61 timer.start();
62 // QPainter makes QGLContext::currentContext() == context()
63 // this may delayed until previous buffer swap finished
55 QPainter painter(this);64 QPainter painter(this);
56 draw(&painter, event);65 t1 = timer.restart();
66 draw(&painter, NULL);
67 //t2 = timer.restart();
68 //glFinish();
69 //t3 = timer.restart();
70 //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3;
71 return t1/1000; // return timer for painter setup
57}72}
5873
59void QtSimpleWaveformWidget::postRender() {74void QtSimpleWaveformWidget::postRender() {
6075
=== modified file 'mixxx/src/waveform/widgets/qtsimplewaveformwidget.h'
--- mixxx/src/waveform/widgets/qtsimplewaveformwidget.h 2012-09-19 21:04:53 +0000
+++ mixxx/src/waveform/widgets/qtsimplewaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -12,19 +12,20 @@
12 virtual ~QtSimpleWaveformWidget();12 virtual ~QtSimpleWaveformWidget();
1313
1414
15 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform;}15 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform; }
1616
17 static inline QString getWaveformWidgetName() { return tr("Simple") + " - Qt";}17 static inline QString getWaveformWidgetName() { return tr("Simple") + " - Qt"; }
18 static inline bool useOpenGl() { return true;}18 static inline bool useOpenGl() { return true; }
19 static inline bool useOpenGLShaders() { return false;}19 static inline bool useOpenGLShaders() { return false; }
20 static inline bool developerOnly() { return false; }
2021
21 protected:22 protected:
22 virtual void castToQWidget();23 virtual void castToQWidget();
23 virtual void paintEvent(QPaintEvent* event);24 virtual void paintEvent(QPaintEvent* event);
24 virtual void postRender();25 virtual void postRender();
26 virtual int render();
2527
26 private:28 private:
27 QtSimpleWaveformWidget() {}
28 friend class WaveformWidgetFactory;29 friend class WaveformWidgetFactory;
29};30};
3031
3132
=== modified file 'mixxx/src/waveform/widgets/qtwaveformwidget.cpp'
--- mixxx/src/waveform/widgets/qtwaveformwidget.cpp 2013-01-04 20:29:33 +0000
+++ mixxx/src/waveform/widgets/qtwaveformwidget.cpp 2013-05-01 22:08:27 +0000
@@ -14,6 +14,8 @@
14#include "waveform/renderers/waveformrenderbeat.h"14#include "waveform/renderers/waveformrenderbeat.h"
15#include "sharedglcontext.h"15#include "sharedglcontext.h"
1616
17#include "util/performancetimer.h"
18
17QtWaveformWidget::QtWaveformWidget( const char* group, QWidget* parent)19QtWaveformWidget::QtWaveformWidget( const char* group, QWidget* parent)
18 : QGLWidget(parent, SharedGLContext::getWidget()),20 : QGLWidget(parent, SharedGLContext::getWidget()),
19 WaveformWidgetAbstract(group) {21 WaveformWidgetAbstract(group) {
@@ -47,11 +49,24 @@
47}49}
4850
49void QtWaveformWidget::paintEvent( QPaintEvent* event) {51void QtWaveformWidget::paintEvent( QPaintEvent* event) {
50 if (QGLContext::currentContext() != context()) {52 Q_UNUSED(event);
51 makeCurrent();53}
52 }54
55int QtWaveformWidget::render() {
56 PerformanceTimer timer;
57 int t1;
58 //int t2, t3;
59 timer.start();
60 // QPainter makes QGLContext::currentContext() == context()
61 // this may delayed until previous buffer swap finished
53 QPainter painter(this);62 QPainter painter(this);
54 draw(&painter, event);63 t1 = timer.restart();
64 draw(&painter, NULL);
65 //t2 = timer.restart();
66 //glFinish();
67 //t3 = timer.restart();
68 //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3;
69 return t1/1000; // return timer for painter setup
55}70}
5671
57void QtWaveformWidget::postRender() {72void QtWaveformWidget::postRender() {
5873
=== modified file 'mixxx/src/waveform/widgets/qtwaveformwidget.h'
--- mixxx/src/waveform/widgets/qtwaveformwidget.h 2012-09-19 21:39:13 +0000
+++ mixxx/src/waveform/widgets/qtwaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -11,19 +11,20 @@
11 QtWaveformWidget(const char* group, QWidget* parent);11 QtWaveformWidget(const char* group, QWidget* parent);
12 virtual ~QtWaveformWidget();12 virtual ~QtWaveformWidget();
1313
14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::QtWaveform;}14 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::QtWaveform; }
1515
16 static inline QString getWaveformWidgetName() { return tr("Filtered") + " - Qt";}16 static inline QString getWaveformWidgetName() { return tr("Filtered") + " - Qt"; }
17 static inline bool useOpenGl() { return true;}17 static inline bool useOpenGl() { return true; }
18 static inline bool useOpenGLShaders() { return false;}18 static inline bool useOpenGLShaders() { return false; }
19 static inline bool developerOnly() { return false; }
1920
20 protected:21 protected:
21 virtual void castToQWidget();22 virtual void castToQWidget();
22 virtual void paintEvent(QPaintEvent* event);23 virtual void paintEvent(QPaintEvent* event);
23 virtual void postRender();24 virtual void postRender();
25 virtual int render();
2426
25 private:27 private:
26 QtWaveformWidget() {}
27 friend class WaveformWidgetFactory;28 friend class WaveformWidgetFactory;
28};29};
2930
3031
=== modified file 'mixxx/src/waveform/widgets/softwarewaveformwidget.h'
--- mixxx/src/waveform/widgets/softwarewaveformwidget.h 2012-11-04 20:33:22 +0000
+++ mixxx/src/waveform/widgets/softwarewaveformwidget.h 2013-05-01 22:08:27 +0000
@@ -10,18 +10,18 @@
10 public:10 public:
11 virtual ~SoftwareWaveformWidget();11 virtual ~SoftwareWaveformWidget();
1212
13 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::SoftwareWaveform;}13 virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::SoftwareWaveform; }
1414
15 static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("Software");}15 static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("Software"); }
16 static inline bool useOpenGl() { return false;}16 static inline bool useOpenGl() { return false; }
17 static inline bool useOpenGLShaders() { return false;}17 static inline bool useOpenGLShaders() { return false; }
18 static inline bool developerOnly() { return false; }
1819
19 protected:20 protected:
20 virtual void castToQWidget();21 virtual void castToQWidget();
21 virtual void paintEvent(QPaintEvent* event);22 virtual void paintEvent(QPaintEvent* event);
2223
23 private:24 private:
24 SoftwareWaveformWidget() {}
25 SoftwareWaveformWidget(const char* group, QWidget* parent);25 SoftwareWaveformWidget(const char* group, QWidget* parent);
26 friend class WaveformWidgetFactory;26 friend class WaveformWidgetFactory;
27};27};
2828
=== modified file 'mixxx/src/waveform/widgets/waveformwidgetabstract.cpp'
--- mixxx/src/waveform/widgets/waveformwidgetabstract.cpp 2012-12-10 17:23:43 +0000
+++ mixxx/src/waveform/widgets/waveformwidgetabstract.cpp 2013-05-01 22:08:27 +0000
@@ -4,15 +4,10 @@
4#include <QtDebug>4#include <QtDebug>
5#include <QWidget>5#include <QWidget>
66
7// Default constructor is only use by the factory to evaluate dynamically
8// WaveformWidget
9WaveformWidgetAbstract::WaveformWidgetAbstract() :
10 WaveformWidgetRenderer() {
11 m_widget = NULL;
12}
137
14WaveformWidgetAbstract::WaveformWidgetAbstract( const char* group) :8WaveformWidgetAbstract::WaveformWidgetAbstract( const char* group)
15 WaveformWidgetRenderer(group) {9 : WaveformWidgetRenderer(group),
10 m_initSuccess(false) {
16 m_widget = NULL;11 m_widget = NULL;
17}12}
1813
@@ -31,17 +26,15 @@
31 }26 }
32}27}
3328
34void WaveformWidgetAbstract::preRender() {29void WaveformWidgetAbstract::preRender(VSyncThread* vsyncThread) {
35 WaveformWidgetRenderer::onPreRender();30 WaveformWidgetRenderer::onPreRender(vsyncThread);
36}31}
3732
38void WaveformWidgetAbstract::render() {33int WaveformWidgetAbstract::render() {
39 if (m_widget) {34 if (m_widget) {
40 if (!m_widget->isVisible()) {35 m_widget->repaint(); // Repaints the widget directly by calling paintEvent()
41 m_widget->show();
42 }
43 m_widget->repaint();
44 }36 }
37 return 0; // Time for Painter setup, unknown in this case
45}38}
4639
47void WaveformWidgetAbstract::resize( int width, int height) {40void WaveformWidgetAbstract::resize( int width, int height) {
4841
=== modified file 'mixxx/src/waveform/widgets/waveformwidgetabstract.h'
--- mixxx/src/waveform/widgets/waveformwidgetabstract.h 2012-09-19 21:04:53 +0000
+++ mixxx/src/waveform/widgets/waveformwidgetabstract.h 2013-05-01 22:08:27 +0000
@@ -8,6 +8,8 @@
8#include "waveformwidgettype.h"8#include "waveformwidgettype.h"
9#include "trackinfoobject.h"9#include "trackinfoobject.h"
1010
11class VSyncThread;
12
11// NOTE(vRince) This class represent objects the waveformwidgetfactory can13// NOTE(vRince) This class represent objects the waveformwidgetfactory can
12// holds, IMPORTANT all WaveformWidgetAbstract MUST inherist QWidget too !! we14// holds, IMPORTANT all WaveformWidgetAbstract MUST inherist QWidget too !! we
13// can't do it here because QWidget and QGLWidget are both QWidgets so they15// can't do it here because QWidget and QGLWidget are both QWidgets so they
@@ -27,9 +29,9 @@
27 void hold();29 void hold();
28 void release();30 void release();
2931
30 virtual void preRender();32 virtual void preRender(VSyncThread* vsyncThread);
31 virtual void render();33 virtual int render();
32 virtual void postRender() {}34 virtual void postRender() {};
3335
34 virtual void resize( int width, int height);36 virtual void resize( int width, int height);
3537
@@ -37,7 +39,6 @@
37 QWidget* m_widget;39 QWidget* m_widget;
38 bool m_initSuccess;40 bool m_initSuccess;
3941
40 WaveformWidgetAbstract();
41 //this is the factory resposability to trigger QWidget casting after constructor42 //this is the factory resposability to trigger QWidget casting after constructor
42 virtual void castToQWidget() = 0;43 virtual void castToQWidget() = 0;
4344
4445
=== modified file 'mixxx/src/waveform/widgets/waveformwidgettype.h'
--- mixxx/src/waveform/widgets/waveformwidgettype.h 2012-12-13 22:46:16 +0000
+++ mixxx/src/waveform/widgets/waveformwidgettype.h 2013-05-01 22:08:27 +0000
@@ -6,13 +6,14 @@
6 enum Type {6 enum Type {
7 EmptyWaveform = 0,7 EmptyWaveform = 0,
8 SoftwareSimpleWaveform, //TODO8 SoftwareSimpleWaveform, //TODO
9 SoftwareWaveform, //TODO9 SoftwareWaveform,
10 QtSimpleWaveform, //TODO10 QtSimpleWaveform,
11 QtWaveform,11 QtWaveform,
12 GLSimpleWaveform,12 GLSimpleWaveform,
13 GLWaveform,13 GLWaveform,
14 GLSLWaveform,14 GLSLWaveform,
15 HSVWaveform,15 HSVWaveform,
16 GLVSyncTest,
16 Count_WaveformwidgetType // Also used as invalid value17 Count_WaveformwidgetType // Also used as invalid value
17 };18 };
18};19};
1920
=== modified file 'mixxx/src/widget/wspinny.cpp'
--- mixxx/src/widget/wspinny.cpp 2013-04-05 23:13:45 +0000
+++ mixxx/src/widget/wspinny.cpp 2013-05-01 22:08:27 +0000
@@ -7,6 +7,7 @@
7#include "controlobject.h"7#include "controlobject.h"
8#include "controlobjectthreadmain.h"8#include "controlobjectthreadmain.h"
9#include "sharedglcontext.h"9#include "sharedglcontext.h"
10#include "visualplayposition.h"
10#include "wspinny.h"11#include "wspinny.h"
1112
12WSpinny::WSpinny(QWidget* parent, VinylControlManager* pVCMan)13WSpinny::WSpinny(QWidget* parent, VinylControlManager* pVCMan)
@@ -16,7 +17,6 @@
16 m_pGhostImage(NULL),17 m_pGhostImage(NULL),
17 m_pPlay(NULL),18 m_pPlay(NULL),
18 m_pPlayPos(NULL),19 m_pPlayPos(NULL),
19 m_pVisualPlayPos(NULL),
20 m_pDuration(NULL),20 m_pDuration(NULL),
21 m_pTrackSamples(NULL),21 m_pTrackSamples(NULL),
22 m_pScratch(NULL),22 m_pScratch(NULL),
@@ -50,7 +50,7 @@
5050
51WSpinny::~WSpinny() {51WSpinny::~WSpinny() {
52 // No need to delete anything if m_group is empty because setup() was not called.52 // No need to delete anything if m_group is empty because setup() was not called.
53 if (!m_group.isEmpty()) {53 if (!m_group.isEmpty()) {
54 WImageStore::deleteImage(m_pBgImage);54 WImageStore::deleteImage(m_pBgImage);
55 WImageStore::deleteImage(m_pFgImage);55 WImageStore::deleteImage(m_pFgImage);
56 WImageStore::deleteImage(m_pGhostImage);56 WImageStore::deleteImage(m_pGhostImage);
@@ -96,8 +96,8 @@
96 ConfigKey(group, "play")));96 ConfigKey(group, "play")));
97 m_pPlayPos = new ControlObjectThreadMain(ControlObject::getControl(97 m_pPlayPos = new ControlObjectThreadMain(ControlObject::getControl(
98 ConfigKey(group, "playposition")));98 ConfigKey(group, "playposition")));
99 m_pVisualPlayPos = new ControlObjectThreadMain(ControlObject::getControl(99 m_pVisualPlayPos = VisualPlayPosition::getVisualPlayPosition(group);
100 ConfigKey(group, "visual_playposition")));100
101 m_pDuration = new ControlObjectThreadMain(ControlObject::getControl(101 m_pDuration = new ControlObjectThreadMain(ControlObject::getControl(
102 ConfigKey(group, "duration")));102 ConfigKey(group, "duration")));
103 m_pTrackSamples = new ControlObjectThreadMain(ControlObject::getControl(103 m_pTrackSamples = new ControlObjectThreadMain(ControlObject::getControl(
@@ -115,8 +115,6 @@
115115
116 m_pSlipEnabled = new ControlObjectThreadMain(ControlObject::getControl(116 m_pSlipEnabled = new ControlObjectThreadMain(ControlObject::getControl(
117 ConfigKey(group, "slip_enabled")));117 ConfigKey(group, "slip_enabled")));
118 m_pSlipPosition = new ControlObjectThreadMain(ControlObject::getControl(
119 ConfigKey(group, "slip_playposition")));
120118
121#ifdef __VINYLCONTROL__119#ifdef __VINYLCONTROL__
122 m_pVinylControlSpeedType = new ControlObjectThreadMain(ControlObject::getControl(120 m_pVinylControlSpeedType = new ControlObjectThreadMain(ControlObject::getControl(
@@ -211,8 +209,9 @@
211 p.save();209 p.save();
212 }210 }
213211
214 double playPosition = m_pVisualPlayPos->get();212 double playPosition = -1;
215 double slipPosition = m_pSlipPosition->get();213 double slipPosition = -1;
214 m_pVisualPlayPos->getPlaySlipAt(0, &playPosition, &slipPosition);
216215
217 if (playPosition != m_dAngleLastPlaypos) {216 if (playPosition != m_dAngleLastPlaypos) {
218 m_fAngle = calculateAngle(playPosition);217 m_fAngle = calculateAngle(playPosition);
219218
=== modified file 'mixxx/src/widget/wspinny.h'
--- mixxx/src/widget/wspinny.h 2013-03-23 12:47:24 +0000
+++ mixxx/src/widget/wspinny.h 2013-05-01 22:08:27 +0000
@@ -11,6 +11,7 @@
11#endif11#endif
1212
13class ControlObjectThreadMain;13class ControlObjectThreadMain;
14class VisualPlayPosition;
1415
15class WSpinny : public QGLWidget {16class WSpinny : public QGLWidget {
16 Q_OBJECT17 Q_OBJECT
@@ -48,7 +49,7 @@
48 QImage* m_pGhostImage;49 QImage* m_pGhostImage;
49 ControlObjectThreadMain* m_pPlay;50 ControlObjectThreadMain* m_pPlay;
50 ControlObjectThreadMain* m_pPlayPos;51 ControlObjectThreadMain* m_pPlayPos;
51 ControlObjectThreadMain* m_pVisualPlayPos;52 VisualPlayPosition* m_pVisualPlayPos;
52 ControlObjectThreadMain* m_pDuration;53 ControlObjectThreadMain* m_pDuration;
53 ControlObjectThreadMain* m_pTrackSamples;54 ControlObjectThreadMain* m_pTrackSamples;
54 ControlObjectThreadMain* m_pTrackSampleRate;55 ControlObjectThreadMain* m_pTrackSampleRate;
@@ -60,7 +61,6 @@
60 ControlObjectThreadMain* m_pVinylControlEnabled;61 ControlObjectThreadMain* m_pVinylControlEnabled;
61 ControlObjectThreadMain* m_pSignalEnabled;62 ControlObjectThreadMain* m_pSignalEnabled;
62 ControlObjectThreadMain* m_pSlipEnabled;63 ControlObjectThreadMain* m_pSlipEnabled;
63 ControlObjectThreadMain* m_pSlipPosition;
6464
65#ifdef __VINYLCONTROL__65#ifdef __VINYLCONTROL__
66 VinylControlManager* m_pVCManager;66 VinylControlManager* m_pVCManager;

Subscribers

People subscribed via source and target branches