Merge lp:~mixxxdevelopers/mixxx/waveform-dejerk into lp:~mixxxdevelopers/mixxx/trunk
- waveform-dejerk
- Merge into trunk
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 | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mixxx Development Team | Pending | ||
Review via email: mp+156977@code.launchpad.net |
Commit message
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 VisualPlayPosit
The Play position for the waveform is adjusted for the actual display time in
VisualPlayPosit
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.
- 3344. By Daniel Schürmann
-
merged from lp:mixxx
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
1 | === modified file 'mixxx/build/depends.py' | |||
2 | --- mixxx/build/depends.py 2013-02-09 00:49:59 +0000 | |||
3 | +++ mixxx/build/depends.py 2013-05-01 22:08:27 +0000 | |||
4 | @@ -632,6 +632,7 @@ | |||
5 | 632 | "waveform/waveform.cpp", | 632 | "waveform/waveform.cpp", |
6 | 633 | "waveform/waveformfactory.cpp", | 633 | "waveform/waveformfactory.cpp", |
7 | 634 | "waveform/waveformwidgetfactory.cpp", | 634 | "waveform/waveformwidgetfactory.cpp", |
8 | 635 | "waveform/vsyncthread.cpp", | ||
9 | 635 | "waveform/renderers/waveformwidgetrenderer.cpp", | 636 | "waveform/renderers/waveformwidgetrenderer.cpp", |
10 | 636 | "waveform/renderers/waveformrendererabstract.cpp", | 637 | "waveform/renderers/waveformrendererabstract.cpp", |
11 | 637 | "waveform/renderers/waveformrenderbackground.cpp", | 638 | "waveform/renderers/waveformrenderbackground.cpp", |
12 | @@ -648,6 +649,7 @@ | |||
13 | 648 | "waveform/renderers/glwaveformrendererfilteredsignal.cpp", | 649 | "waveform/renderers/glwaveformrendererfilteredsignal.cpp", |
14 | 649 | "waveform/renderers/glwaveformrenderersimplesignal.cpp", | 650 | "waveform/renderers/glwaveformrenderersimplesignal.cpp", |
15 | 650 | "waveform/renderers/glslwaveformrenderersignal.cpp", | 651 | "waveform/renderers/glslwaveformrenderersignal.cpp", |
16 | 652 | "waveform/renderers/glvsynctestrenderer.cpp", | ||
17 | 651 | 653 | ||
18 | 652 | "waveform/renderers/waveformsignalcolors.cpp", | 654 | "waveform/renderers/waveformsignalcolors.cpp", |
19 | 653 | 655 | ||
20 | @@ -664,6 +666,7 @@ | |||
21 | 664 | "waveform/widgets/qtsimplewaveformwidget.cpp", | 666 | "waveform/widgets/qtsimplewaveformwidget.cpp", |
22 | 665 | "waveform/widgets/glwaveformwidget.cpp", | 667 | "waveform/widgets/glwaveformwidget.cpp", |
23 | 666 | "waveform/widgets/glsimplewaveformwidget.cpp", | 668 | "waveform/widgets/glsimplewaveformwidget.cpp", |
24 | 669 | "waveform/widgets/glvsynctestwidget.cpp", | ||
25 | 667 | 670 | ||
26 | 668 | "waveform/widgets/glslwaveformwidget.cpp", | 671 | "waveform/widgets/glslwaveformwidget.cpp", |
27 | 669 | 672 | ||
28 | @@ -696,6 +699,7 @@ | |||
29 | 696 | "soundmanagerutil.cpp", | 699 | "soundmanagerutil.cpp", |
30 | 697 | "dlgprefrecord.cpp", | 700 | "dlgprefrecord.cpp", |
31 | 698 | "playerinfo.cpp", | 701 | "playerinfo.cpp", |
32 | 702 | "visualplayposition.cpp", | ||
33 | 699 | 703 | ||
34 | 700 | "recording/enginerecord.cpp", | 704 | "recording/enginerecord.cpp", |
35 | 701 | "recording/encoder.cpp", | 705 | "recording/encoder.cpp", |
36 | 702 | 706 | ||
37 | === added file 'mixxx/src/controlobjectbase.h' | |||
38 | --- mixxx/src/controlobjectbase.h 1970-01-01 00:00:00 +0000 | |||
39 | +++ mixxx/src/controlobjectbase.h 2013-05-01 22:08:27 +0000 | |||
40 | @@ -0,0 +1,147 @@ | |||
41 | 1 | |||
42 | 2 | #ifndef CONTROLOBJECTBASE_H_ | ||
43 | 3 | #define CONTROLOBJECTBASE_H_ | ||
44 | 4 | |||
45 | 5 | #include <QAtomicInt> | ||
46 | 6 | #include <QObject> | ||
47 | 7 | |||
48 | 8 | static const int cReaderSlotCnt = 7; | ||
49 | 9 | |||
50 | 10 | template<typename T> | ||
51 | 11 | class ControlObjectRingValue { | ||
52 | 12 | public: | ||
53 | 13 | ControlObjectRingValue() | ||
54 | 14 | : m_value(T()), | ||
55 | 15 | m_readerSlots(cReaderSlotCnt) { | ||
56 | 16 | } | ||
57 | 17 | |||
58 | 18 | int tryGet(T* value) { | ||
59 | 19 | // Read while consuming one readerSlot | ||
60 | 20 | bool originalSlots = m_readerSlots.fetchAndAddAcquire(-1); | ||
61 | 21 | if (originalSlots) { | ||
62 | 22 | *value = m_value; | ||
63 | 23 | } | ||
64 | 24 | (void)m_readerSlots.fetchAndAddRelease(1); | ||
65 | 25 | return originalSlots; | ||
66 | 26 | } | ||
67 | 27 | |||
68 | 28 | bool trySet(const T& value) { | ||
69 | 29 | // try to lock this element entirely for reading | ||
70 | 30 | if (m_readerSlots.testAndSetAcquire(cReaderSlotCnt, 0)) { | ||
71 | 31 | m_value = value; | ||
72 | 32 | m_readerSlots.fetchAndAddRelease(cReaderSlotCnt); | ||
73 | 33 | return true; | ||
74 | 34 | } | ||
75 | 35 | return false; | ||
76 | 36 | } | ||
77 | 37 | |||
78 | 38 | private: | ||
79 | 39 | T m_value; | ||
80 | 40 | QAtomicInt m_readerSlots; | ||
81 | 41 | }; | ||
82 | 42 | |||
83 | 43 | // Common implementation for all Types | ||
84 | 44 | template<typename T, bool ATOMIC = false> | ||
85 | 45 | class ControlObjectValue { | ||
86 | 46 | public: | ||
87 | 47 | inline T getValue() { | ||
88 | 48 | T value = T(); | ||
89 | 49 | unsigned int index = (unsigned int)m_readIndex | ||
90 | 50 | % (cReaderSlotCnt + 1); | ||
91 | 51 | while (m_ring[index].tryGet(&value) == 0) { | ||
92 | 52 | // We are here if | ||
93 | 53 | // 1) there are more then cReaderSlotCnt reader (get) reading the same value or | ||
94 | 54 | // 2) the formerly current value is locked by a writer | ||
95 | 55 | // Case 1 is prevented by enough reader slots and schould not happen | ||
96 | 56 | // Case 2 happens when the a reader is delayed after reading the | ||
97 | 57 | // m_currentIndex and the writers have written cReaderSlotCnt times so that the | ||
98 | 58 | // formally current value is locked again for writing. | ||
99 | 59 | // In both cases reading the less recent value will fix it. | ||
100 | 60 | index = (index - 1) % (cReaderSlotCnt + 1); | ||
101 | 61 | } | ||
102 | 62 | return value; | ||
103 | 63 | } | ||
104 | 64 | |||
105 | 65 | inline void setValue(const T& value) { | ||
106 | 66 | // Test if we can read atomic | ||
107 | 67 | // This test is const and will be mad only at compile time | ||
108 | 68 | unsigned int index; | ||
109 | 69 | do { | ||
110 | 70 | index = (unsigned int)m_writeIndex.fetchAndAddAcquire(1) | ||
111 | 71 | % (cReaderSlotCnt + 1); | ||
112 | 72 | // This will be repeated if the value is locked | ||
113 | 73 | // 1) by an other writer writing at the same time or | ||
114 | 74 | // 2) a delayed reader is still blocking the formerly current value | ||
115 | 75 | // In both cases writing to the next value will fix it. | ||
116 | 76 | } while (!m_ring[index].trySet(value)); | ||
117 | 77 | m_readIndex = (int)index; | ||
118 | 78 | } | ||
119 | 79 | |||
120 | 80 | protected: | ||
121 | 81 | ControlObjectValue() | ||
122 | 82 | : m_readIndex(0), | ||
123 | 83 | m_writeIndex(1) { | ||
124 | 84 | } | ||
125 | 85 | |||
126 | 86 | private: | ||
127 | 87 | ControlObjectRingValue<T> m_ring[cReaderSlotCnt+1]; | ||
128 | 88 | QAtomicInt m_readIndex; | ||
129 | 89 | QAtomicInt m_writeIndex; | ||
130 | 90 | }; | ||
131 | 91 | |||
132 | 92 | // Specialized Template for atomic types | ||
133 | 93 | template<typename T> | ||
134 | 94 | class ControlObjectValue<T, true> { | ||
135 | 95 | public: | ||
136 | 96 | inline T getValue() { | ||
137 | 97 | return m_value; | ||
138 | 98 | } | ||
139 | 99 | |||
140 | 100 | inline void setValue(const T& value) { | ||
141 | 101 | m_value = value; | ||
142 | 102 | } | ||
143 | 103 | |||
144 | 104 | protected: | ||
145 | 105 | ControlObjectValue() | ||
146 | 106 | : m_value(T()) { | ||
147 | 107 | } | ||
148 | 108 | |||
149 | 109 | private: | ||
150 | 110 | T m_value; | ||
151 | 111 | }; | ||
152 | 112 | |||
153 | 113 | // Note: Qt does not support templates for signal and slots | ||
154 | 114 | // So the typified ControlObject has to handle the Event Queue connections | ||
155 | 115 | template<typename T> | ||
156 | 116 | class ControlObjectBase | ||
157 | 117 | : public ControlObjectValue<T, sizeof(T) <= sizeof(void*)> { | ||
158 | 118 | public: | ||
159 | 119 | ControlObjectBase() | ||
160 | 120 | : ControlObjectValue<T, sizeof(T) <= sizeof(void*)>() { | ||
161 | 121 | } | ||
162 | 122 | }; | ||
163 | 123 | |||
164 | 124 | |||
165 | 125 | template<typename T> | ||
166 | 126 | class ControlObjectThreadBase { | ||
167 | 127 | public: | ||
168 | 128 | ControlObjectThreadBase(ControlObjectBase<T>* pControlObject) | ||
169 | 129 | : m_pControlObject(pControlObject) { | ||
170 | 130 | } | ||
171 | 131 | virtual ~ControlObjectThreadBase(); | ||
172 | 132 | |||
173 | 133 | inline T get() const { | ||
174 | 134 | return m_pControlObject->get(); | ||
175 | 135 | } | ||
176 | 136 | |||
177 | 137 | inline void set(const T& value) { | ||
178 | 138 | return m_pControlObject->get(); | ||
179 | 139 | } | ||
180 | 140 | |||
181 | 141 | private: | ||
182 | 142 | ControlObjectBase<T>* m_pControlObject; | ||
183 | 143 | }; | ||
184 | 144 | |||
185 | 145 | |||
186 | 146 | #endif // CONTROLOBJECTBASE_H_ | ||
187 | 147 | |||
188 | 0 | 148 | ||
189 | === modified file 'mixxx/src/dlgprefcontrols.cpp' | |||
190 | --- mixxx/src/dlgprefcontrols.cpp 2013-01-27 23:04:37 +0000 | |||
191 | +++ mixxx/src/dlgprefcontrols.cpp 2013-05-01 22:08:27 +0000 | |||
192 | @@ -44,7 +44,6 @@ | |||
193 | 44 | ConfigObject<ConfigValue> * pConfig) | 44 | ConfigObject<ConfigValue> * pConfig) |
194 | 45 | : QWidget(parent) { | 45 | : QWidget(parent) { |
195 | 46 | m_pConfig = pConfig; | 46 | m_pConfig = pConfig; |
196 | 47 | m_timer = -1; | ||
197 | 48 | m_mixxx = mixxx; | 47 | m_mixxx = mixxx; |
198 | 49 | m_pSkinLoader = pSkinLoader; | 48 | m_pSkinLoader = pSkinLoader; |
199 | 50 | m_pPlayerManager = pPlayerManager; | 49 | m_pPlayerManager = pPlayerManager; |
200 | @@ -597,24 +596,14 @@ | |||
201 | 597 | WaveformWidgetFactory::instance()->setOverviewNormalized(normalize); | 596 | WaveformWidgetFactory::instance()->setOverviewNormalized(normalize); |
202 | 598 | } | 597 | } |
203 | 599 | 598 | ||
222 | 600 | void DlgPrefControls::onShow() { | 599 | void DlgPrefControls::slotWaveformMeasured(float frameRate, int rtErrorCnt) { |
223 | 601 | m_timer = startTimer(100); //refresh actual frame rate every 100 ms | 600 | frameRateAverage->setText( |
224 | 602 | } | 601 | QString::number((double)frameRate, 'f', 2) + |
225 | 603 | 602 | " e" + | |
226 | 604 | void DlgPrefControls::onHide() { | 603 | QString::number(rtErrorCnt)); |
227 | 605 | if (m_timer != -1) { | 604 | } |
228 | 606 | killTimer(m_timer); | 605 | |
229 | 607 | } | 606 | void DlgPrefControls::initWaveformControl() { |
212 | 608 | } | ||
213 | 609 | |||
214 | 610 | void DlgPrefControls::timerEvent(QTimerEvent * /*event*/) { | ||
215 | 611 | //Just to refresh actual framrate any time the controller is modified | ||
216 | 612 | frameRateAverage->setText(QString::number( | ||
217 | 613 | WaveformWidgetFactory::instance()->getActualFrameRate())); | ||
218 | 614 | } | ||
219 | 615 | |||
220 | 616 | void DlgPrefControls::initWaveformControl() | ||
221 | 617 | { | ||
230 | 618 | waveformTypeComboBox->clear(); | 607 | waveformTypeComboBox->clear(); |
231 | 619 | WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); | 608 | WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); |
232 | 620 | 609 | ||
233 | @@ -626,15 +615,17 @@ | |||
234 | 626 | WaveformWidgetType::Type currentType = factory->getType(); | 615 | WaveformWidgetType::Type currentType = factory->getType(); |
235 | 627 | int currentIndex = -1; | 616 | int currentIndex = -1; |
236 | 628 | 617 | ||
239 | 629 | std::vector<WaveformWidgetAbstractHandle> handles = factory->getAvailableTypes(); | 618 | QVector<WaveformWidgetAbstractHandle> handles = factory->getAvailableTypes(); |
240 | 630 | for (unsigned int i = 0; i < handles.size(); i++) { | 619 | for (int i = 0; i < handles.size(); i++) { |
241 | 631 | waveformTypeComboBox->addItem(handles[i].getDisplayName()); | 620 | waveformTypeComboBox->addItem(handles[i].getDisplayName()); |
243 | 632 | if (handles[i].getType() == currentType) | 621 | if (handles[i].getType() == currentType) { |
244 | 633 | currentIndex = i; | 622 | currentIndex = i; |
245 | 623 | } | ||
246 | 634 | } | 624 | } |
247 | 635 | 625 | ||
249 | 636 | if (currentIndex != -1) | 626 | if (currentIndex != -1) { |
250 | 637 | waveformTypeComboBox->setCurrentIndex(currentIndex); | 627 | waveformTypeComboBox->setCurrentIndex(currentIndex); |
251 | 628 | } | ||
252 | 638 | 629 | ||
253 | 639 | frameRateSpinBox->setValue(factory->getFrameRate()); | 630 | frameRateSpinBox->setValue(factory->getFrameRate()); |
254 | 640 | 631 | ||
255 | @@ -671,6 +662,8 @@ | |||
256 | 671 | connect(normalizeOverviewCheckBox,SIGNAL(toggled(bool)), | 662 | connect(normalizeOverviewCheckBox,SIGNAL(toggled(bool)), |
257 | 672 | this,SLOT(slotSetNormalizeOverview(bool))); | 663 | this,SLOT(slotSetNormalizeOverview(bool))); |
258 | 673 | 664 | ||
259 | 665 | connect(WaveformWidgetFactory::instance(), SIGNAL(waveformMeasured(float,int)), | ||
260 | 666 | this, SLOT(slotWaveformMeasured(float,int))); | ||
261 | 674 | } | 667 | } |
262 | 675 | 668 | ||
263 | 676 | //Returns TRUE if skin fits to screen resolution, FALSE otherwise | 669 | //Returns TRUE if skin fits to screen resolution, FALSE otherwise |
264 | 677 | 670 | ||
265 | === modified file 'mixxx/src/dlgprefcontrols.h' | |||
266 | --- mixxx/src/dlgprefcontrols.h 2013-01-27 23:04:37 +0000 | |||
267 | +++ mixxx/src/dlgprefcontrols.h 2013-05-01 22:08:27 +0000 | |||
268 | @@ -73,12 +73,7 @@ | |||
269 | 73 | void slotSetVisualGainMid(double gain); | 73 | void slotSetVisualGainMid(double gain); |
270 | 74 | void slotSetVisualGainHigh(double gain); | 74 | void slotSetVisualGainHigh(double gain); |
271 | 75 | void slotSetNormalizeOverview( bool normalize); | 75 | void slotSetNormalizeOverview( bool normalize); |
278 | 76 | 76 | void slotWaveformMeasured(float frameRate, int rtErrorCnt); | |
273 | 77 | virtual void onShow(); | ||
274 | 78 | virtual void onHide(); | ||
275 | 79 | |||
276 | 80 | protected: | ||
277 | 81 | void timerEvent(QTimerEvent *); | ||
279 | 82 | 77 | ||
280 | 83 | private: | 78 | private: |
281 | 84 | void initWaveformControl(); | 79 | void initWaveformControl(); |
282 | 85 | 80 | ||
283 | === modified file 'mixxx/src/engine/bpmcontrol.cpp' | |||
284 | --- mixxx/src/engine/bpmcontrol.cpp 2013-03-31 16:56:35 +0000 | |||
285 | +++ mixxx/src/engine/bpmcontrol.cpp 2013-05-01 22:08:27 +0000 | |||
286 | @@ -8,6 +8,7 @@ | |||
287 | 8 | 8 | ||
288 | 9 | #include "engine/enginebuffer.h" | 9 | #include "engine/enginebuffer.h" |
289 | 10 | #include "engine/bpmcontrol.h" | 10 | #include "engine/bpmcontrol.h" |
290 | 11 | #include "visualplayposition.h" | ||
291 | 11 | #include "engine/enginechannel.h" | 12 | #include "engine/enginechannel.h" |
292 | 12 | #include "engine/enginemaster.h" | 13 | #include "engine/enginemaster.h" |
293 | 13 | 14 | ||
294 | @@ -318,8 +319,8 @@ | |||
295 | 318 | double dThisPosition = getCurrentSample(); | 319 | double dThisPosition = getCurrentSample(); |
296 | 319 | double dOtherLength = ControlObject::getControl( | 320 | double dOtherLength = ControlObject::getControl( |
297 | 320 | ConfigKey(pOtherEngineBuffer->getGroup(), "track_samples"))->get(); | 321 | ConfigKey(pOtherEngineBuffer->getGroup(), "track_samples"))->get(); |
300 | 321 | double dOtherEnginePlayPos = ControlObject::getControl( | 322 | double dOtherEnginePlayPos = |
301 | 322 | ConfigKey(pOtherEngineBuffer->getGroup(), "visual_playposition"))->get(); | 323 | VisualPlayPosition::getVisualPlayPosition(pOtherEngineBuffer->getGroup())->getEnginePlayPos(); |
302 | 323 | double dOtherPosition = dOtherLength * dOtherEnginePlayPos; | 324 | double dOtherPosition = dOtherLength * dOtherEnginePlayPos; |
303 | 324 | 325 | ||
304 | 325 | double dThisPrevBeat = m_pBeats->findPrevBeat(dThisPosition); | 326 | double dThisPrevBeat = m_pBeats->findPrevBeat(dThisPosition); |
305 | 326 | 327 | ||
306 | === modified file 'mixxx/src/engine/enginebuffer.cpp' | |||
307 | --- mixxx/src/engine/enginebuffer.cpp 2013-04-23 18:15:21 +0000 | |||
308 | +++ mixxx/src/engine/enginebuffer.cpp 2013-05-01 22:08:27 +0000 | |||
309 | @@ -37,6 +37,7 @@ | |||
310 | 37 | #include "engine/ratecontrol.h" | 37 | #include "engine/ratecontrol.h" |
311 | 38 | #include "engine/bpmcontrol.h" | 38 | #include "engine/bpmcontrol.h" |
312 | 39 | #include "engine/quantizecontrol.h" | 39 | #include "engine/quantizecontrol.h" |
313 | 40 | #include "visualplayposition.h" | ||
314 | 40 | #include "util/timer.h" | 41 | #include "util/timer.h" |
315 | 41 | 42 | ||
316 | 42 | #ifdef __VINYLCONTROL__ | 43 | #ifdef __VINYLCONTROL__ |
317 | @@ -148,7 +149,6 @@ | |||
318 | 148 | connect(m_pSlipButton, SIGNAL(valueChangedFromEngine(double)), | 149 | connect(m_pSlipButton, SIGNAL(valueChangedFromEngine(double)), |
319 | 149 | this, SLOT(slotControlSlip(double)), | 150 | this, SLOT(slotControlSlip(double)), |
320 | 150 | Qt::DirectConnection); | 151 | Qt::DirectConnection); |
321 | 151 | m_pSlipPosition = new ControlObject(ConfigKey(m_group, "slip_playposition")); | ||
322 | 152 | 152 | ||
323 | 153 | // Actual rate (used in visuals, not for control) | 153 | // Actual rate (used in visuals, not for control) |
324 | 154 | m_rateEngine = new ControlObject(ConfigKey(m_group, "rateEngine")); | 154 | m_rateEngine = new ControlObject(ConfigKey(m_group, "rateEngine")); |
325 | @@ -165,8 +165,7 @@ | |||
326 | 165 | Qt::DirectConnection); | 165 | Qt::DirectConnection); |
327 | 166 | 166 | ||
328 | 167 | // Control used to communicate ratio playpos to GUI thread | 167 | // Control used to communicate ratio playpos to GUI thread |
331 | 168 | m_visualPlaypos = new ControlPotmeter( | 168 | m_visualPlayPos = VisualPlayPosition::getVisualPlayPosition(m_group); |
330 | 169 | ConfigKey(m_group, "visual_playposition"), kMinPlayposRange, kMaxPlayposRange); | ||
332 | 170 | 169 | ||
333 | 171 | m_pRepeat = new ControlPushButton(ConfigKey(m_group, "repeat")); | 170 | m_pRepeat = new ControlPushButton(ConfigKey(m_group, "repeat")); |
334 | 172 | m_pRepeat->setButtonMode(ControlPushButton::TOGGLE); | 171 | m_pRepeat->setButtonMode(ControlPushButton::TOGGLE); |
335 | @@ -251,11 +250,9 @@ | |||
336 | 251 | delete m_stopButton; | 250 | delete m_stopButton; |
337 | 252 | delete m_rateEngine; | 251 | delete m_rateEngine; |
338 | 253 | delete m_playposSlider; | 252 | delete m_playposSlider; |
339 | 254 | delete m_visualPlaypos; | ||
340 | 255 | delete m_visualBpm; | 253 | delete m_visualBpm; |
341 | 256 | 254 | ||
342 | 257 | delete m_pSlipButton; | 255 | delete m_pSlipButton; |
343 | 258 | delete m_pSlipPosition; | ||
344 | 259 | delete m_pRepeat; | 256 | delete m_pRepeat; |
345 | 260 | 257 | ||
346 | 261 | delete m_pTrackSamples; | 258 | delete m_pTrackSamples; |
347 | @@ -384,7 +381,7 @@ | |||
348 | 384 | int iTrackSampleRate, | 381 | int iTrackSampleRate, |
349 | 385 | int iTrackNumSamples) { | 382 | int iTrackNumSamples) { |
350 | 386 | m_pause.lock(); | 383 | m_pause.lock(); |
352 | 387 | m_visualPlaypos->set(-1); | 384 | m_visualPlayPos->setInvalid(); |
353 | 388 | m_pCurrentTrack = pTrack; | 385 | m_pCurrentTrack = pTrack; |
354 | 389 | m_file_srate_old = iTrackSampleRate; | 386 | m_file_srate_old = iTrackSampleRate; |
355 | 390 | m_file_length_old = iTrackNumSamples; | 387 | m_file_length_old = iTrackNumSamples; |
356 | @@ -527,13 +524,11 @@ | |||
357 | 527 | // TODO(rryan): Should this filepos instead be the RAMAN current | 524 | // TODO(rryan): Should this filepos instead be the RAMAN current |
358 | 528 | // position? filepos_play could be out of date. | 525 | // position? filepos_play could be out of date. |
359 | 529 | m_dSlipPosition = m_filepos_play; | 526 | m_dSlipPosition = m_filepos_play; |
360 | 530 | m_pSlipPosition->set(fractionalPlayposFromAbsolute(m_dSlipPosition)); | ||
361 | 531 | m_dSlipRate = m_rate_old; | 527 | m_dSlipRate = m_rate_old; |
362 | 532 | } else { | 528 | } else { |
363 | 533 | // TODO(owen) assuming that looping will get canceled properly | 529 | // TODO(owen) assuming that looping will get canceled properly |
364 | 534 | slotControlSeekAbs(m_dSlipPosition); | 530 | slotControlSeekAbs(m_dSlipPosition); |
365 | 535 | m_dSlipPosition = 0; | 531 | m_dSlipPosition = 0; |
366 | 536 | m_pSlipPosition->set(0); | ||
367 | 537 | } | 532 | } |
368 | 538 | } | 533 | } |
369 | 539 | 534 | ||
370 | @@ -577,7 +572,6 @@ | |||
371 | 577 | // Update the slipped position | 572 | // Update the slipped position |
372 | 578 | if (m_bSlipEnabled) { | 573 | if (m_bSlipEnabled) { |
373 | 579 | m_dSlipPosition += static_cast<double>(iBufferSize) * m_dSlipRate; | 574 | m_dSlipPosition += static_cast<double>(iBufferSize) * m_dSlipRate; |
374 | 580 | m_pSlipPosition->set(fractionalPlayposFromAbsolute(m_dSlipPosition)); | ||
375 | 581 | } | 575 | } |
376 | 582 | 576 | ||
377 | 583 | // Scratching always disables keylock because keylock sounds terrible | 577 | // Scratching always disables keylock because keylock sounds terrible |
378 | @@ -852,6 +846,9 @@ | |||
379 | 852 | m_iSamplesCalculated += iBufferSize; | 846 | m_iSamplesCalculated += iBufferSize; |
380 | 853 | 847 | ||
381 | 854 | double fFractionalPlaypos = fractionalPlayposFromAbsolute(m_filepos_play); | 848 | double fFractionalPlaypos = fractionalPlayposFromAbsolute(m_filepos_play); |
382 | 849 | if(rate > 0 && fFractionalPlaypos == 1.0) { | ||
383 | 850 | rate = 0; | ||
384 | 851 | } | ||
385 | 855 | 852 | ||
386 | 856 | // Update indicators that are only updated after every | 853 | // Update indicators that are only updated after every |
387 | 857 | // sampleRate/kiUpdateRate samples processed. (e.g. playposSlider, | 854 | // sampleRate/kiUpdateRate samples processed. (e.g. playposSlider, |
388 | @@ -874,7 +871,9 @@ | |||
389 | 874 | 871 | ||
390 | 875 | // Update visual control object, this needs to be done more often than the | 872 | // Update visual control object, this needs to be done more often than the |
391 | 876 | // rateEngine and playpos slider | 873 | // rateEngine and playpos slider |
393 | 877 | m_visualPlaypos->set(fFractionalPlaypos); | 874 | m_visualPlayPos->set(fFractionalPlaypos, rate, |
394 | 875 | (double)iBufferSize/m_file_length_old, | ||
395 | 876 | fractionalPlayposFromAbsolute(m_dSlipPosition)); | ||
396 | 878 | } | 877 | } |
397 | 879 | 878 | ||
398 | 880 | void EngineBuffer::hintReader(const double dRate) { | 879 | void EngineBuffer::hintReader(const double dRate) { |
399 | 881 | 880 | ||
400 | === modified file 'mixxx/src/engine/enginebuffer.h' | |||
401 | --- mixxx/src/engine/enginebuffer.h 2013-02-03 18:50:24 +0000 | |||
402 | +++ mixxx/src/engine/enginebuffer.h 2013-05-01 22:08:27 +0000 | |||
403 | @@ -49,6 +49,7 @@ | |||
404 | 49 | class EngineBufferScaleLinear; | 49 | class EngineBufferScaleLinear; |
405 | 50 | class EngineBufferScaleST; | 50 | class EngineBufferScaleST; |
406 | 51 | class EngineWorkerScheduler; | 51 | class EngineWorkerScheduler; |
407 | 52 | class VisualPlayPosition; | ||
408 | 52 | class EngineMaster; | 53 | class EngineMaster; |
409 | 53 | 54 | ||
410 | 54 | struct Hint; | 55 | struct Hint; |
411 | @@ -225,13 +226,11 @@ | |||
412 | 225 | ControlObject* m_fwdButton; | 226 | ControlObject* m_fwdButton; |
413 | 226 | ControlObject* m_backButton; | 227 | ControlObject* m_backButton; |
414 | 227 | ControlPushButton* m_pSlipButton; | 228 | ControlPushButton* m_pSlipButton; |
415 | 228 | ControlObject* m_pSlipPosition; | ||
416 | 229 | 229 | ||
417 | 230 | ControlObject* m_rateEngine; | 230 | ControlObject* m_rateEngine; |
418 | 231 | ControlObject* m_visualBpm; | 231 | ControlObject* m_visualBpm; |
419 | 232 | ControlObject* m_pMasterRate; | 232 | ControlObject* m_pMasterRate; |
420 | 233 | ControlPotmeter* m_playposSlider; | 233 | ControlPotmeter* m_playposSlider; |
421 | 234 | ControlPotmeter* m_visualPlaypos; | ||
422 | 235 | ControlObject* m_pSampleRate; | 234 | ControlObject* m_pSampleRate; |
423 | 236 | ControlPushButton* m_pKeylock; | 235 | ControlPushButton* m_pKeylock; |
424 | 237 | 236 | ||
425 | @@ -277,6 +276,8 @@ | |||
426 | 277 | CSAMPLE* m_pCrossFadeBuffer; | 276 | CSAMPLE* m_pCrossFadeBuffer; |
427 | 278 | int m_iCrossFadeSamples; | 277 | int m_iCrossFadeSamples; |
428 | 279 | int m_iLastBufferSize; | 278 | int m_iLastBufferSize; |
429 | 279 | |||
430 | 280 | VisualPlayPosition* m_visualPlayPos; | ||
431 | 280 | }; | 281 | }; |
432 | 281 | 282 | ||
433 | 282 | #endif | 283 | #endif |
434 | 283 | 284 | ||
435 | === modified file 'mixxx/src/main.cpp' | |||
436 | --- mixxx/src/main.cpp 2013-04-28 18:46:48 +0000 | |||
437 | +++ mixxx/src/main.cpp 2013-05-01 22:08:27 +0000 | |||
438 | @@ -40,6 +40,10 @@ | |||
439 | 40 | #include <ladspa/ladspaloader.h> | 40 | #include <ladspa/ladspaloader.h> |
440 | 41 | #endif | 41 | #endif |
441 | 42 | 42 | ||
442 | 43 | #ifdef Q_WS_X11 | ||
443 | 44 | #include <X11/Xlib.h> | ||
444 | 45 | #endif | ||
445 | 46 | |||
446 | 43 | #ifdef __WINDOWS__ | 47 | #ifdef __WINDOWS__ |
447 | 44 | #ifdef DEBUGCONSOLE | 48 | #ifdef DEBUGCONSOLE |
448 | 45 | #include <io.h> // Debug Console | 49 | #include <io.h> // Debug Console |
449 | @@ -139,6 +143,11 @@ | |||
450 | 139 | 143 | ||
451 | 140 | int main(int argc, char * argv[]) | 144 | int main(int argc, char * argv[]) |
452 | 141 | { | 145 | { |
453 | 146 | |||
454 | 147 | #ifdef Q_WS_X11 | ||
455 | 148 | XInitThreads(); | ||
456 | 149 | #endif | ||
457 | 150 | |||
458 | 142 | // Check if an instance of Mixxx is already running | 151 | // Check if an instance of Mixxx is already running |
459 | 143 | // See http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication | 152 | // See http://qt.nokia.com/products/appdev/add-on-products/catalog/4/Utilities/qtsingleapplication |
460 | 144 | 153 | ||
461 | 145 | 154 | ||
462 | === modified file 'mixxx/src/mixxx.cpp' | |||
463 | --- mixxx/src/mixxx.cpp 2013-05-01 20:29:44 +0000 | |||
464 | +++ mixxx/src/mixxx.cpp 2013-05-01 22:08:27 +0000 | |||
465 | @@ -387,6 +387,7 @@ | |||
466 | 387 | this, SLOT(slotSyncControlSystem())); | 387 | this, SLOT(slotSyncControlSystem())); |
467 | 388 | 388 | ||
468 | 389 | WaveformWidgetFactory::create(); | 389 | WaveformWidgetFactory::create(); |
469 | 390 | WaveformWidgetFactory::instance()->startVSync(this); | ||
470 | 390 | WaveformWidgetFactory::instance()->setConfig(m_pConfig); | 391 | WaveformWidgetFactory::instance()->setConfig(m_pConfig); |
471 | 391 | 392 | ||
472 | 392 | m_pSkinLoader = new SkinLoader(m_pConfig); | 393 | m_pSkinLoader = new SkinLoader(m_pConfig); |
473 | @@ -1609,7 +1610,6 @@ | |||
474 | 1609 | 1610 | ||
475 | 1610 | m_pView->hide(); | 1611 | m_pView->hide(); |
476 | 1611 | 1612 | ||
477 | 1612 | WaveformWidgetFactory::instance()->stop(); | ||
478 | 1613 | WaveformWidgetFactory::instance()->destroyWidgets(); | 1613 | WaveformWidgetFactory::instance()->destroyWidgets(); |
479 | 1614 | 1614 | ||
480 | 1615 | // Workaround for changing skins while fullscreen, just go out of fullscreen | 1615 | // Workaround for changing skins while fullscreen, just go out of fullscreen |
481 | @@ -1658,8 +1658,6 @@ | |||
482 | 1658 | initPosition.y() + (initSize.height() - m_pView->height()) / 2); | 1658 | initPosition.y() + (initSize.height() - m_pView->height()) / 2); |
483 | 1659 | } | 1659 | } |
484 | 1660 | 1660 | ||
485 | 1661 | WaveformWidgetFactory::instance()->start(); | ||
486 | 1662 | |||
487 | 1663 | #ifdef __APPLE__ | 1661 | #ifdef __APPLE__ |
488 | 1664 | // Original the following line fixes issue on OSX where menu bar went away | 1662 | // Original the following line fixes issue on OSX where menu bar went away |
489 | 1665 | // after a skin change. It was original surrounded by #if __OSX__ | 1663 | // after a skin change. It was original surrounded by #if __OSX__ |
490 | 1666 | 1664 | ||
491 | === modified file 'mixxx/src/sounddeviceportaudio.cpp' | |||
492 | --- mixxx/src/sounddeviceportaudio.cpp 2013-03-21 22:29:13 +0000 | |||
493 | +++ mixxx/src/sounddeviceportaudio.cpp 2013-05-01 22:08:27 +0000 | |||
494 | @@ -25,6 +25,7 @@ | |||
495 | 25 | #include "sounddeviceportaudio.h" | 25 | #include "sounddeviceportaudio.h" |
496 | 26 | #include "soundmanagerutil.h" | 26 | #include "soundmanagerutil.h" |
497 | 27 | #include "controlobject.h" | 27 | #include "controlobject.h" |
498 | 28 | #include "visualplayposition.h" | ||
499 | 28 | #include "util/timer.h" | 29 | #include "util/timer.h" |
500 | 29 | 30 | ||
501 | 30 | SoundDevicePortAudio::SoundDevicePortAudio(ConfigObject<ConfigValue> *config, SoundManager *sm, | 31 | SoundDevicePortAudio::SoundDevicePortAudio(ConfigObject<ConfigValue> *config, SoundManager *sm, |
502 | @@ -326,6 +327,7 @@ | |||
503 | 326 | m_bSetThreadPriority = true; | 327 | m_bSetThreadPriority = true; |
504 | 327 | } | 328 | } |
505 | 328 | 329 | ||
506 | 330 | VisualPlayPosition::setTimeInfo(timeInfo); | ||
507 | 329 | if (!m_undeflowUpdateCount) { | 331 | if (!m_undeflowUpdateCount) { |
508 | 330 | if (statusFlags & (paOutputUnderflow | paInputOverflow)) { | 332 | if (statusFlags & (paOutputUnderflow | paInputOverflow)) { |
509 | 331 | if (m_pMasterUnderflowCount) { | 333 | if (m_pMasterUnderflowCount) { |
510 | 332 | 334 | ||
511 | === added file 'mixxx/src/visualplayposition.cpp' | |||
512 | --- mixxx/src/visualplayposition.cpp 1970-01-01 00:00:00 +0000 | |||
513 | +++ mixxx/src/visualplayposition.cpp 2013-05-01 22:08:27 +0000 | |||
514 | @@ -0,0 +1,109 @@ | |||
515 | 1 | |||
516 | 2 | #include <qdebug.h> | ||
517 | 3 | |||
518 | 4 | #include "visualplayposition.h" | ||
519 | 5 | #include "controlobjectthreadmain.h" | ||
520 | 6 | #include "controlobject.h" | ||
521 | 7 | #include "waveform/waveformwidgetfactory.h" | ||
522 | 8 | #include "mathstuff.h" | ||
523 | 9 | #include "waveform/vsyncthread.h" | ||
524 | 10 | |||
525 | 11 | |||
526 | 12 | //static | ||
527 | 13 | QMap<QString, VisualPlayPosition*> VisualPlayPosition::m_listVisualPlayPosition; | ||
528 | 14 | const PaStreamCallbackTimeInfo* VisualPlayPosition::m_timeInfo; | ||
529 | 15 | PerformanceTimer VisualPlayPosition::m_timeInfoTime; | ||
530 | 16 | |||
531 | 17 | VisualPlayPosition::VisualPlayPosition() : | ||
532 | 18 | m_valid(false) { | ||
533 | 19 | |||
534 | 20 | m_audioBufferSize = new ControlObjectThreadMain( | ||
535 | 21 | ControlObject::getControl(ConfigKey("[Master]","audio_buffer_size"))); | ||
536 | 22 | } | ||
537 | 23 | |||
538 | 24 | VisualPlayPosition::~VisualPlayPosition() { | ||
539 | 25 | |||
540 | 26 | } | ||
541 | 27 | |||
542 | 28 | // This function must be called only form the engine thread (PA callback) | ||
543 | 29 | void VisualPlayPosition::set(double playPos, double rate, | ||
544 | 30 | double positionStep, double pSlipPosition) { | ||
545 | 31 | VisualPlayPositionData data; | ||
546 | 32 | |||
547 | 33 | data.m_referenceTime = m_timeInfoTime; | ||
548 | 34 | // Time from reference time to Buffer at DAC in µs | ||
549 | 35 | data.m_timeDac = (m_timeInfo->outputBufferDacTime - m_timeInfo->currentTime) * 1000000; | ||
550 | 36 | data.m_playPos = playPos; | ||
551 | 37 | data.m_rate = rate; | ||
552 | 38 | data.m_positionStep = positionStep; | ||
553 | 39 | data.m_pSlipPosition = pSlipPosition; | ||
554 | 40 | |||
555 | 41 | // Atomic write | ||
556 | 42 | m_data.setValue(data); | ||
557 | 43 | m_valid = true; | ||
558 | 44 | } | ||
559 | 45 | |||
560 | 46 | double VisualPlayPosition::getAt(VSyncThread* vsyncThread) { | ||
561 | 47 | //static double testPos = 0; | ||
562 | 48 | //testPos += 0.000017759; //0.000016608; // 1.46257e-05; | ||
563 | 49 | //return testPos; | ||
564 | 50 | |||
565 | 51 | if (m_valid) { | ||
566 | 52 | VisualPlayPositionData data = m_data.getValue(); | ||
567 | 53 | int usRefToVSync = vsyncThread->usFromTimerToNextSync(&data.m_referenceTime); | ||
568 | 54 | int offset = usRefToVSync - data.m_timeDac; | ||
569 | 55 | double playPos = data.m_playPos; // load playPos for the first sample in Buffer | ||
570 | 56 | playPos += data.m_positionStep * offset * data.m_rate / m_audioBufferSize->get() / 1000; | ||
571 | 57 | //qDebug() << "delta Pos" << playPos - m_playPosOld << offset; | ||
572 | 58 | m_playPosOld = playPos; | ||
573 | 59 | return playPos; | ||
574 | 60 | } | ||
575 | 61 | return -1; | ||
576 | 62 | } | ||
577 | 63 | |||
578 | 64 | void VisualPlayPosition::getPlaySlipAt(int usFromNow, double* playPosition, double* slipPosition) { | ||
579 | 65 | //static double testPos = 0; | ||
580 | 66 | //testPos += 0.000017759; //0.000016608; // 1.46257e-05; | ||
581 | 67 | //return testPos; | ||
582 | 68 | |||
583 | 69 | if (m_valid) { | ||
584 | 70 | VisualPlayPositionData data = m_data.getValue(); | ||
585 | 71 | int usElapsed = data.m_referenceTime.elapsed() / 1000; | ||
586 | 72 | int dacFromNow = usElapsed - data.m_timeDac; | ||
587 | 73 | int offset = dacFromNow - usFromNow; | ||
588 | 74 | double playPos = data.m_playPos; // load playPos for the first sample in Buffer | ||
589 | 75 | playPos += data.m_positionStep * offset * data.m_rate / m_audioBufferSize->get() / 1000; | ||
590 | 76 | *playPosition = playPos; | ||
591 | 77 | *slipPosition = data.m_pSlipPosition; | ||
592 | 78 | } | ||
593 | 79 | } | ||
594 | 80 | |||
595 | 81 | double VisualPlayPosition::getEnginePlayPos() { | ||
596 | 82 | if (m_valid) { | ||
597 | 83 | VisualPlayPositionData data = m_data.getValue(); | ||
598 | 84 | return data.m_playPos; | ||
599 | 85 | } else { | ||
600 | 86 | return -1; | ||
601 | 87 | } | ||
602 | 88 | } | ||
603 | 89 | |||
604 | 90 | //static | ||
605 | 91 | VisualPlayPosition* VisualPlayPosition::getVisualPlayPosition(QString group) { | ||
606 | 92 | VisualPlayPosition* vpp = m_listVisualPlayPosition[group]; | ||
607 | 93 | if (!vpp) { | ||
608 | 94 | vpp = new VisualPlayPosition(); | ||
609 | 95 | m_listVisualPlayPosition[group] = vpp; | ||
610 | 96 | } | ||
611 | 97 | return vpp; | ||
612 | 98 | } | ||
613 | 99 | |||
614 | 100 | //static | ||
615 | 101 | void VisualPlayPosition::setTimeInfo(const PaStreamCallbackTimeInfo *timeInfo) { | ||
616 | 102 | m_timeInfo = timeInfo; | ||
617 | 103 | m_timeInfoTime.start(); | ||
618 | 104 | //qDebug() << "TimeInfo" << (timeInfo->currentTime - floor(timeInfo->currentTime)) << (timeInfo->outputBufferDacTime - floor(timeInfo->outputBufferDacTime)); | ||
619 | 105 | //m_timeInfo.currentTime = timeInfo->currentTime; | ||
620 | 106 | //m_timeInfo.inputBufferAdcTime = timeInfo->inputBufferAdcTime; | ||
621 | 107 | //m_timeInfo.outputBufferDacTime = timeInfo->outputBufferDacTime; | ||
622 | 108 | } | ||
623 | 109 | |||
624 | 0 | 110 | ||
625 | === added file 'mixxx/src/visualplayposition.h' | |||
626 | --- mixxx/src/visualplayposition.h 1970-01-01 00:00:00 +0000 | |||
627 | +++ mixxx/src/visualplayposition.h 2013-05-01 22:08:27 +0000 | |||
628 | @@ -0,0 +1,57 @@ | |||
629 | 1 | #ifndef VISUALPLAYPOSITION_H | ||
630 | 2 | #define VISUALPLAYPOSITION_H | ||
631 | 3 | |||
632 | 4 | #include <portaudio.h> | ||
633 | 5 | #include "util/performancetimer.h" | ||
634 | 6 | #include "controlobjectbase.h" | ||
635 | 7 | |||
636 | 8 | #include <QMutex> | ||
637 | 9 | #include <QTime> | ||
638 | 10 | #include <QMap> | ||
639 | 11 | #include <QAtomicPointer> | ||
640 | 12 | |||
641 | 13 | class ControlObjectThreadMain; | ||
642 | 14 | class VSyncThread; | ||
643 | 15 | |||
644 | 16 | class VisualPlayPositionData { | ||
645 | 17 | public: | ||
646 | 18 | PerformanceTimer m_referenceTime; | ||
647 | 19 | int m_timeDac; | ||
648 | 20 | double m_playPos; | ||
649 | 21 | double m_rate; | ||
650 | 22 | double m_positionStep; | ||
651 | 23 | double m_pSlipPosition; | ||
652 | 24 | }; | ||
653 | 25 | |||
654 | 26 | |||
655 | 27 | class VisualPlayPosition | ||
656 | 28 | { | ||
657 | 29 | public: | ||
658 | 30 | VisualPlayPosition(); | ||
659 | 31 | ~VisualPlayPosition(); | ||
660 | 32 | |||
661 | 33 | void set(double playPos, double rate, double positionStep, double pSlipPosition); | ||
662 | 34 | double getAt(VSyncThread* vsyncThread); | ||
663 | 35 | void getPlaySlipAt(int usFromNow, double* playPosition, double* slipPosition); | ||
664 | 36 | double getEnginePlayPos(); | ||
665 | 37 | static VisualPlayPosition* getVisualPlayPosition(QString group); | ||
666 | 38 | static void setTimeInfo(const PaStreamCallbackTimeInfo *timeInfo); | ||
667 | 39 | void setInvalid() { m_valid = false; }; | ||
668 | 40 | |||
669 | 41 | |||
670 | 42 | private: | ||
671 | 43 | ControlObjectBase<VisualPlayPositionData> m_data; | ||
672 | 44 | double m_playPosOld; | ||
673 | 45 | int m_deltatime; | ||
674 | 46 | ControlObjectThreadMain* m_audioBufferSize; | ||
675 | 47 | PaTime m_outputBufferDacTime; | ||
676 | 48 | bool m_valid; | ||
677 | 49 | |||
678 | 50 | static QMap<QString, VisualPlayPosition*> m_listVisualPlayPosition; | ||
679 | 51 | static const PaStreamCallbackTimeInfo* m_timeInfo; | ||
680 | 52 | static PerformanceTimer m_timeInfoTime; | ||
681 | 53 | |||
682 | 54 | }; | ||
683 | 55 | |||
684 | 56 | #endif // VISUALPLAYPOSITION_H | ||
685 | 57 | |||
686 | 0 | 58 | ||
687 | === added file 'mixxx/src/waveform/renderers/glvsynctestrenderer.cpp' | |||
688 | --- mixxx/src/waveform/renderers/glvsynctestrenderer.cpp 1970-01-01 00:00:00 +0000 | |||
689 | +++ mixxx/src/waveform/renderers/glvsynctestrenderer.cpp 2013-05-01 22:08:27 +0000 | |||
690 | @@ -0,0 +1,133 @@ | |||
691 | 1 | #include "glvsynctestrenderer.h" | ||
692 | 2 | |||
693 | 3 | #include "waveformwidgetrenderer.h" | ||
694 | 4 | #include "waveform/waveform.h" | ||
695 | 5 | |||
696 | 6 | #include "waveform/waveformwidgetfactory.h" | ||
697 | 7 | |||
698 | 8 | #include "util/performancetimer.h" | ||
699 | 9 | |||
700 | 10 | #include <qgl.h> | ||
701 | 11 | |||
702 | 12 | GLVSyncTestRenderer::GLVSyncTestRenderer( | ||
703 | 13 | WaveformWidgetRenderer* waveformWidgetRenderer) | ||
704 | 14 | : WaveformRendererSignalBase(waveformWidgetRenderer), | ||
705 | 15 | m_drawcount(0) { | ||
706 | 16 | } | ||
707 | 17 | |||
708 | 18 | GLVSyncTestRenderer::~GLVSyncTestRenderer() { | ||
709 | 19 | } | ||
710 | 20 | |||
711 | 21 | void GLVSyncTestRenderer::onSetup(const QDomNode &node) { | ||
712 | 22 | Q_UNUSED(node); | ||
713 | 23 | } | ||
714 | 24 | |||
715 | 25 | inline void setPoint(QPointF& point, qreal x, qreal y) { | ||
716 | 26 | point.setX(x); | ||
717 | 27 | point.setY(y); | ||
718 | 28 | } | ||
719 | 29 | |||
720 | 30 | void GLVSyncTestRenderer::draw(QPainter* painter, QPaintEvent* /*event*/) { | ||
721 | 31 | |||
722 | 32 | PerformanceTimer timer; | ||
723 | 33 | //int t5, t6, t7, t8, t9, t10, t11, t12, t13; | ||
724 | 34 | |||
725 | 35 | |||
726 | 36 | timer.start(); | ||
727 | 37 | |||
728 | 38 | TrackPointer pTrack = m_waveformRenderer->getTrackInfo(); | ||
729 | 39 | if (!pTrack) { | ||
730 | 40 | return; | ||
731 | 41 | } | ||
732 | 42 | |||
733 | 43 | const Waveform* waveform = pTrack->getWaveform(); | ||
734 | 44 | if (waveform == NULL) { | ||
735 | 45 | return; | ||
736 | 46 | } | ||
737 | 47 | |||
738 | 48 | const int dataSize = waveform->getDataSize(); | ||
739 | 49 | if (dataSize <= 1) { | ||
740 | 50 | return; | ||
741 | 51 | } | ||
742 | 52 | |||
743 | 53 | const WaveformData* data = waveform->data(); | ||
744 | 54 | if (data == NULL) { | ||
745 | 55 | return; | ||
746 | 56 | } | ||
747 | 57 | |||
748 | 58 | double firstVisualIndex = m_waveformRenderer->getFirstDisplayedPosition() * dataSize; | ||
749 | 59 | double lastVisualIndex = m_waveformRenderer->getLastDisplayedPosition() * dataSize; | ||
750 | 60 | |||
751 | 61 | const int firstIndex = int(firstVisualIndex + 0.5); | ||
752 | 62 | firstVisualIndex = firstIndex - firstIndex % 2; | ||
753 | 63 | |||
754 | 64 | const int lastIndex = int(lastVisualIndex + 0.5); | ||
755 | 65 | lastVisualIndex = lastIndex + lastIndex % 2; | ||
756 | 66 | |||
757 | 67 | //t5 = timer.restart(); // 910 | ||
758 | 68 | |||
759 | 69 | // Reset device for native painting | ||
760 | 70 | painter->beginNativePainting(); | ||
761 | 71 | |||
762 | 72 | //t6 = timer.restart(); // 29,150 | ||
763 | 73 | |||
764 | 74 | glEnable(GL_BLEND); | ||
765 | 75 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
766 | 76 | |||
767 | 77 | const QColor& color = m_pColors->getSignalColor(); | ||
768 | 78 | |||
769 | 79 | //t7 = timer.restart(); // 5,770 | ||
770 | 80 | |||
771 | 81 | WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); | ||
772 | 82 | const double visualGain = factory->getVisualGain(::WaveformWidgetFactory::All); | ||
773 | 83 | |||
774 | 84 | float maxAll[2]; | ||
775 | 85 | |||
776 | 86 | glMatrixMode(GL_PROJECTION); | ||
777 | 87 | glPushMatrix(); | ||
778 | 88 | glLoadIdentity(); | ||
779 | 89 | |||
780 | 90 | //t8 = timer.restart(); // 2,611 | ||
781 | 91 | |||
782 | 92 | if (m_alignment == Qt::AlignCenter) { | ||
783 | 93 | glOrtho(firstVisualIndex, lastVisualIndex, -255.0, 255.0, -10.0, 10.0); | ||
784 | 94 | } else if (m_alignment == Qt::AlignBottom) { | ||
785 | 95 | glOrtho(firstVisualIndex, lastVisualIndex, 0.0, 255.0, -10.0, 10.0); | ||
786 | 96 | } else { | ||
787 | 97 | glOrtho(firstVisualIndex, lastVisualIndex, 255.0, 0.0, -10.0, 10.0); | ||
788 | 98 | } | ||
789 | 99 | |||
790 | 100 | //t9 = timer.restart(); // 1,320 | ||
791 | 101 | |||
792 | 102 | glMatrixMode(GL_MODELVIEW); | ||
793 | 103 | glPushMatrix(); | ||
794 | 104 | glLoadIdentity(); | ||
795 | 105 | |||
796 | 106 | //t10 = timer.restart(); // 915 | ||
797 | 107 | |||
798 | 108 | if (++m_drawcount & 1) { | ||
799 | 109 | glClearColor(1.0f, 1.0f, 1.0f, 1.0f); | ||
800 | 110 | glColor3f(1.0f, 1.0f, 1.0f); | ||
801 | 111 | } else { | ||
802 | 112 | glClearColor(1.0f, 0.0f, 0.0f, 0.0f); | ||
803 | 113 | glColor3f(1.0f, 0.0f, 0.0f); | ||
804 | 114 | } | ||
805 | 115 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | ||
806 | 116 | glRectf(0, 0, 1, 1); | ||
807 | 117 | |||
808 | 118 | //t11 = timer.restart(); // 217,985 | ||
809 | 119 | |||
810 | 120 | glEnd(); | ||
811 | 121 | glPopMatrix(); | ||
812 | 122 | glMatrixMode(GL_PROJECTION); | ||
813 | 123 | glPopMatrix(); | ||
814 | 124 | |||
815 | 125 | //t12 = timer.restart(); // 22,426 | ||
816 | 126 | painter->endNativePainting(); | ||
817 | 127 | |||
818 | 128 | //t13 = timer.restart(); // 1,430 | ||
819 | 129 | |||
820 | 130 | //qDebug() << t5 << t6 << t7 << t8 << t9 << t10 << t11 << t12 << t13; | ||
821 | 131 | |||
822 | 132 | //qDebug() << timer.restart(); // 129,498 | ||
823 | 133 | } | ||
824 | 0 | 134 | ||
825 | === added file 'mixxx/src/waveform/renderers/glvsynctestrenderer.h' | |||
826 | --- mixxx/src/waveform/renderers/glvsynctestrenderer.h 1970-01-01 00:00:00 +0000 | |||
827 | +++ mixxx/src/waveform/renderers/glvsynctestrenderer.h 2013-05-01 22:08:27 +0000 | |||
828 | @@ -0,0 +1,19 @@ | |||
829 | 1 | #ifndef GLVSYNCTESTRENDERER_H | ||
830 | 2 | #define GLVSYNCTESTRENDERER_H | ||
831 | 3 | |||
832 | 4 | #include "waveformrenderersignalbase.h" | ||
833 | 5 | |||
834 | 6 | class ControlObject; | ||
835 | 7 | |||
836 | 8 | class GLVSyncTestRenderer : public WaveformRendererSignalBase { | ||
837 | 9 | public: | ||
838 | 10 | explicit GLVSyncTestRenderer( WaveformWidgetRenderer* waveformWidgetRenderer); | ||
839 | 11 | virtual ~GLVSyncTestRenderer(); | ||
840 | 12 | |||
841 | 13 | virtual void onSetup(const QDomNode &node); | ||
842 | 14 | virtual void draw(QPainter* painter, QPaintEvent* event); | ||
843 | 15 | private: | ||
844 | 16 | int m_drawcount; | ||
845 | 17 | }; | ||
846 | 18 | |||
847 | 19 | #endif // GLVSYNCTESTRENDERER_H | ||
848 | 0 | 20 | ||
849 | === modified file 'mixxx/src/waveform/renderers/waveformrenderbeat.cpp' | |||
850 | --- mixxx/src/waveform/renderers/waveformrenderbeat.cpp 2013-04-12 15:06:58 +0000 | |||
851 | +++ mixxx/src/waveform/renderers/waveformrenderbeat.cpp 2013-05-01 22:08:27 +0000 | |||
852 | @@ -74,7 +74,7 @@ | |||
853 | 74 | 74 | ||
854 | 75 | while (it->hasNext()) { | 75 | while (it->hasNext()) { |
855 | 76 | int beatPosition = it->next(); | 76 | int beatPosition = it->next(); |
857 | 77 | m_waveformRenderer->regulateVisualSample(beatPosition); | 77 | // m_waveformRenderer->regulateVisualSample(beatPosition); |
858 | 78 | double xBeatPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(beatPosition); | 78 | double xBeatPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(beatPosition); |
859 | 79 | 79 | ||
860 | 80 | painter->setPen(beatPen); | 80 | painter->setPen(beatPen); |
861 | 81 | 81 | ||
862 | === modified file 'mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp' | |||
863 | --- mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp 2013-01-28 13:06:12 +0000 | |||
864 | +++ mixxx/src/waveform/renderers/waveformrendererendoftrack.cpp 2013-05-01 22:08:27 +0000 | |||
865 | @@ -13,6 +13,8 @@ | |||
866 | 13 | #include "widget/wskincolor.h" | 13 | #include "widget/wskincolor.h" |
867 | 14 | #include "widget/wwidget.h" | 14 | #include "widget/wwidget.h" |
868 | 15 | 15 | ||
869 | 16 | #include "util/timer.h" | ||
870 | 17 | |||
871 | 16 | WaveformRendererEndOfTrack::WaveformRendererEndOfTrack( | 18 | WaveformRendererEndOfTrack::WaveformRendererEndOfTrack( |
872 | 17 | WaveformWidgetRenderer* waveformWidgetRenderer) | 19 | WaveformWidgetRenderer* waveformWidgetRenderer) |
873 | 18 | : WaveformRendererAbstract(waveformWidgetRenderer), | 20 | : WaveformRendererAbstract(waveformWidgetRenderer), |
874 | @@ -61,14 +63,20 @@ | |||
875 | 61 | } | 63 | } |
876 | 62 | 64 | ||
877 | 63 | void WaveformRendererEndOfTrack::onResize() { | 65 | void WaveformRendererEndOfTrack::onResize() { |
878 | 64 | m_rect = QRect( 0, 0, m_waveformRenderer->getWidth(), m_waveformRenderer->getHeight()); | ||
879 | 65 | m_backRects.resize(4); | 66 | m_backRects.resize(4); |
880 | 66 | for (int i = 0; i < 4; i++) { | 67 | for (int i = 0; i < 4; i++) { |
881 | 67 | m_backRects[i].setTop(0); | 68 | m_backRects[i].setTop(0); |
882 | 68 | m_backRects[i].setBottom(m_waveformRenderer->getHeight()); | 69 | m_backRects[i].setBottom(m_waveformRenderer->getHeight()); |
884 | 69 | m_backRects[i].setLeft(m_waveformRenderer->getWidth()/2+i*m_waveformRenderer->getWidth()/8); | 70 | m_backRects[i].setLeft(m_waveformRenderer->getWidth()/2 + |
885 | 71 | i*m_waveformRenderer->getWidth()/8); | ||
886 | 70 | m_backRects[i].setRight(m_waveformRenderer->getWidth()); | 72 | m_backRects[i].setRight(m_waveformRenderer->getWidth()); |
887 | 71 | } | 73 | } |
888 | 74 | /* | ||
889 | 75 | m_gradient.setStart(m_waveformRenderer->getWidth()/2, 0); | ||
890 | 76 | m_gradient.setFinalStop(m_waveformRenderer->getWidth(), 0); | ||
891 | 77 | m_gradient.setColorAt(0, Qt::transparent); | ||
892 | 78 | m_gradient.setColorAt(1, m_color); | ||
893 | 79 | */ | ||
894 | 72 | } | 80 | } |
895 | 73 | 81 | ||
896 | 74 | void WaveformRendererEndOfTrack::draw(QPainter* painter, | 82 | void WaveformRendererEndOfTrack::draw(QPainter* painter, |
897 | @@ -121,6 +129,8 @@ | |||
898 | 121 | //qDebug() << "EndOfTrack ON"; | 129 | //qDebug() << "EndOfTrack ON"; |
899 | 122 | } | 130 | } |
900 | 123 | 131 | ||
901 | 132 | ScopedTimer t("WaveformRendererEndOfTrack::draw"); | ||
902 | 133 | |||
903 | 124 | const int elapsed = m_timer.elapsed() % m_blinkingPeriodMillis; | 134 | const int elapsed = m_timer.elapsed() % m_blinkingPeriodMillis; |
904 | 125 | 135 | ||
905 | 126 | const double blickIntensity = (double)(2 * abs(elapsed - m_blinkingPeriodMillis/2)) / | 136 | const double blickIntensity = (double)(2 * abs(elapsed - m_blinkingPeriodMillis/2)) / |
906 | @@ -139,5 +149,9 @@ | |||
907 | 139 | painter->setPen(QPen(Qt::transparent)); | 149 | painter->setPen(QPen(Qt::transparent)); |
908 | 140 | painter->setBrush(m_color); | 150 | painter->setBrush(m_color); |
909 | 141 | painter->drawRects(m_backRects); | 151 | painter->drawRects(m_backRects); |
910 | 152 | //painter->setOpacity(0.5 * criticalIntensity * blickIntensity); | ||
911 | 153 | //painter->fillRect(m_waveformRenderer->getWidth()/2, 1, | ||
912 | 154 | // m_waveformRenderer->getWidth() - 2, m_waveformRenderer->getHeight() - 2, | ||
913 | 155 | // m_gradient); | ||
914 | 142 | painter->restore(); | 156 | painter->restore(); |
915 | 143 | } | 157 | } |
916 | 144 | 158 | ||
917 | === modified file 'mixxx/src/waveform/renderers/waveformrendererendoftrack.h' | |||
918 | --- mixxx/src/waveform/renderers/waveformrendererendoftrack.h 2012-12-14 01:26:04 +0000 | |||
919 | +++ mixxx/src/waveform/renderers/waveformrendererendoftrack.h 2013-05-01 22:08:27 +0000 | |||
920 | @@ -3,6 +3,7 @@ | |||
921 | 3 | 3 | ||
922 | 4 | #include <QColor> | 4 | #include <QColor> |
923 | 5 | #include <QTime> | 5 | #include <QTime> |
924 | 6 | #include <QLinearGradient> | ||
925 | 6 | 7 | ||
926 | 7 | #include "util.h" | 8 | #include "util.h" |
927 | 8 | #include "waveformrendererabstract.h" | 9 | #include "waveformrendererabstract.h" |
928 | @@ -35,9 +36,9 @@ | |||
929 | 35 | int m_blinkingPeriodMillis; | 36 | int m_blinkingPeriodMillis; |
930 | 36 | double m_remainingTimeTriggerSeconds; | 37 | double m_remainingTimeTriggerSeconds; |
931 | 37 | 38 | ||
932 | 38 | QRect m_rect; | ||
933 | 39 | QVector<QRect> m_backRects; | 39 | QVector<QRect> m_backRects; |
934 | 40 | QPen m_pen; | 40 | QPen m_pen; |
935 | 41 | QLinearGradient m_gradient; | ||
936 | 41 | 42 | ||
937 | 42 | DISALLOW_COPY_AND_ASSIGN(WaveformRendererEndOfTrack); | 43 | DISALLOW_COPY_AND_ASSIGN(WaveformRendererEndOfTrack); |
938 | 43 | }; | 44 | }; |
939 | 44 | 45 | ||
940 | === added file 'mixxx/src/waveform/renderers/waveformrendererhsv.cpp' | |||
941 | --- mixxx/src/waveform/renderers/waveformrendererhsv.cpp 1970-01-01 00:00:00 +0000 | |||
942 | +++ mixxx/src/waveform/renderers/waveformrendererhsv.cpp 2013-05-01 22:08:27 +0000 | |||
943 | @@ -0,0 +1,177 @@ | |||
944 | 1 | #include "waveformrendererhsv.h" | ||
945 | 2 | |||
946 | 3 | #include "waveformwidgetrenderer.h" | ||
947 | 4 | #include "waveform/waveform.h" | ||
948 | 5 | #include "waveform/waveformwidgetfactory.h" | ||
949 | 6 | |||
950 | 7 | #include "widget/wskincolor.h" | ||
951 | 8 | #include "trackinfoobject.h" | ||
952 | 9 | #include "widget/wwidget.h" | ||
953 | 10 | |||
954 | 11 | #include "defs.h" | ||
955 | 12 | |||
956 | 13 | #include "controlobjectthreadmain.h" | ||
957 | 14 | |||
958 | 15 | WaveformRendererHSV::WaveformRendererHSV( | ||
959 | 16 | WaveformWidgetRenderer* waveformWidgetRenderer) | ||
960 | 17 | : WaveformRendererSignalBase( waveformWidgetRenderer) { | ||
961 | 18 | } | ||
962 | 19 | |||
963 | 20 | WaveformRendererHSV::~WaveformRendererHSV() { | ||
964 | 21 | } | ||
965 | 22 | |||
966 | 23 | void WaveformRendererHSV::onSetup(const QDomNode& node) { | ||
967 | 24 | Q_UNUSED(node); | ||
968 | 25 | } | ||
969 | 26 | |||
970 | 27 | void WaveformRendererHSV::draw(QPainter* painter, | ||
971 | 28 | QPaintEvent* /*event*/) { | ||
972 | 29 | const TrackPointer trackInfo = m_waveformRenderer->getTrackInfo(); | ||
973 | 30 | if (!trackInfo) { | ||
974 | 31 | return; | ||
975 | 32 | } | ||
976 | 33 | |||
977 | 34 | const Waveform* waveform = trackInfo->getWaveform(); | ||
978 | 35 | if (waveform == NULL) { | ||
979 | 36 | return; | ||
980 | 37 | } | ||
981 | 38 | |||
982 | 39 | const int dataSize = waveform->getDataSize(); | ||
983 | 40 | if (dataSize <= 1) { | ||
984 | 41 | return; | ||
985 | 42 | } | ||
986 | 43 | |||
987 | 44 | const WaveformData* data = waveform->data(); | ||
988 | 45 | if (data == NULL) { | ||
989 | 46 | return; | ||
990 | 47 | } | ||
991 | 48 | |||
992 | 49 | painter->save(); | ||
993 | 50 | painter->setRenderHints(QPainter::Antialiasing, false); | ||
994 | 51 | painter->setRenderHints(QPainter::HighQualityAntialiasing, false); | ||
995 | 52 | painter->setRenderHints(QPainter::SmoothPixmapTransform, false); | ||
996 | 53 | painter->setWorldMatrixEnabled(false); | ||
997 | 54 | painter->resetTransform(); | ||
998 | 55 | |||
999 | 56 | const double firstVisualIndex = m_waveformRenderer->getFirstDisplayedPosition() * dataSize; | ||
1000 | 57 | const double lastVisualIndex = m_waveformRenderer->getLastDisplayedPosition() * dataSize; | ||
1001 | 58 | |||
1002 | 59 | const double offset = firstVisualIndex; | ||
1003 | 60 | |||
1004 | 61 | // Represents the # of waveform data points per horizontal pixel. | ||
1005 | 62 | const double gain = (lastVisualIndex - firstVisualIndex) / | ||
1006 | 63 | (double)m_waveformRenderer->getWidth(); | ||
1007 | 64 | |||
1008 | 65 | float allGain(1.0); | ||
1009 | 66 | allGain = m_waveformRenderer->getGain(); | ||
1010 | 67 | |||
1011 | 68 | WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); | ||
1012 | 69 | allGain *= factory->getVisualGain(::WaveformWidgetFactory::All); | ||
1013 | 70 | |||
1014 | 71 | // Save HSV of waveform color | ||
1015 | 72 | double h,s,v; | ||
1016 | 73 | |||
1017 | 74 | // Get base color of waveform in the HSV format (s and v isn't use) | ||
1018 | 75 | m_pColors->getLowColor().getHsvF(&h,&s,&v); | ||
1019 | 76 | |||
1020 | 77 | QColor color; | ||
1021 | 78 | float lo, hi, total; | ||
1022 | 79 | |||
1023 | 80 | const float halfHeight = (float)m_waveformRenderer->getHeight()/2.0; | ||
1024 | 81 | |||
1025 | 82 | const float heightFactor = allGain*halfHeight/255.0; | ||
1026 | 83 | |||
1027 | 84 | //draw reference line | ||
1028 | 85 | painter->setPen(m_axesColor); | ||
1029 | 86 | painter->drawLine(0,halfHeight,m_waveformRenderer->getWidth(),halfHeight); | ||
1030 | 87 | |||
1031 | 88 | for (int x = 0; x < m_waveformRenderer->getWidth(); ++x) { | ||
1032 | 89 | // Width of the x position in visual indices. | ||
1033 | 90 | const double xSampleWidth = gain * x; | ||
1034 | 91 | |||
1035 | 92 | // Effective visual index of x | ||
1036 | 93 | const double xVisualSampleIndex = xSampleWidth + offset; | ||
1037 | 94 | |||
1038 | 95 | // Our current pixel (x) corresponds to a number of visual samples | ||
1039 | 96 | // (visualSamplerPerPixel) in our waveform object. We take the max of | ||
1040 | 97 | // all the data points on either side of xVisualSampleIndex within a | ||
1041 | 98 | // window of 'maxSamplingRange' visual samples to measure the maximum | ||
1042 | 99 | // data point contained by this pixel. | ||
1043 | 100 | double maxSamplingRange = gain / 2.0; | ||
1044 | 101 | |||
1045 | 102 | // Since xVisualSampleIndex is in visual-samples (e.g. R,L,R,L) we want | ||
1046 | 103 | // to check +/- maxSamplingRange frames, not samples. To do this, divide | ||
1047 | 104 | // xVisualSampleIndex by 2. Since frames indices are integers, we round | ||
1048 | 105 | // to the nearest integer by adding 0.5 before casting to int. | ||
1049 | 106 | int visualFrameStart = int(xVisualSampleIndex / 2.0 - maxSamplingRange + 0.5); | ||
1050 | 107 | int visualFrameStop = int(xVisualSampleIndex / 2.0 + maxSamplingRange + 0.5); | ||
1051 | 108 | const int lastVisualFrame = dataSize / 2 - 1; | ||
1052 | 109 | |||
1053 | 110 | // We now know that some subset of [visualFrameStart, visualFrameStop] | ||
1054 | 111 | // lies within the valid range of visual frames. Clamp | ||
1055 | 112 | // visualFrameStart/Stop to within [0, lastVisualFrame]. | ||
1056 | 113 | visualFrameStart = math_max(math_min(lastVisualFrame, visualFrameStart), 0); | ||
1057 | 114 | visualFrameStop = math_max(math_min(lastVisualFrame, visualFrameStop), 0); | ||
1058 | 115 | |||
1059 | 116 | int visualIndexStart = visualFrameStart * 2; | ||
1060 | 117 | int visualIndexStop = visualFrameStop * 2; | ||
1061 | 118 | |||
1062 | 119 | int maxLow[2] = {0, 0}; | ||
1063 | 120 | int maxHigh[2] = {0, 0}; | ||
1064 | 121 | int maxMid[2] = {0, 0}; | ||
1065 | 122 | int maxAll[2] = {0, 0}; | ||
1066 | 123 | |||
1067 | 124 | for (int i = visualIndexStart; | ||
1068 | 125 | i >= 0 && i + 1 < dataSize && i + 1 <= visualIndexStop; i += 2) { | ||
1069 | 126 | const WaveformData& waveformData = *(data + i); | ||
1070 | 127 | const WaveformData& waveformDataNext = *(data + i + 1); | ||
1071 | 128 | maxLow[0] = math_max(maxLow[0], (int)waveformData.filtered.low); | ||
1072 | 129 | maxLow[1] = math_max(maxLow[1], (int)waveformDataNext.filtered.low); | ||
1073 | 130 | maxMid[0] = math_max(maxMid[0], (int)waveformData.filtered.mid); | ||
1074 | 131 | maxMid[1] = math_max(maxMid[1], (int)waveformDataNext.filtered.mid); | ||
1075 | 132 | maxHigh[0] = math_max(maxHigh[0], (int)waveformData.filtered.high); | ||
1076 | 133 | maxHigh[1] = math_max(maxHigh[1], (int)waveformDataNext.filtered.high); | ||
1077 | 134 | maxAll[0] = math_max( maxAll[0], (int)waveformData.filtered.all); | ||
1078 | 135 | maxAll[1] = math_max( maxAll[1], (int)waveformDataNext.filtered.all); | ||
1079 | 136 | } | ||
1080 | 137 | |||
1081 | 138 | if( maxAll[0] && maxAll[1] ) { | ||
1082 | 139 | // Calculate sum, to normalize | ||
1083 | 140 | // Also multiply on 1.2 to prevent very dark or light color | ||
1084 | 141 | total = (maxLow[0] + maxLow[1] + maxMid[0] + maxMid[1] + maxHigh[0] + maxHigh[1]) * 1.2; | ||
1085 | 142 | |||
1086 | 143 | // prevent division by zero | ||
1087 | 144 | if( total > 0 ) | ||
1088 | 145 | { | ||
1089 | 146 | // Normalize low and high (mid not need, because it not change the color) | ||
1090 | 147 | lo = (maxLow[0] + maxLow[1]) / total; | ||
1091 | 148 | hi = (maxHigh[0] + maxHigh[1]) / total; | ||
1092 | 149 | } | ||
1093 | 150 | else | ||
1094 | 151 | lo = hi = 0.0; | ||
1095 | 152 | |||
1096 | 153 | // Set color | ||
1097 | 154 | color.setHsvF(h, 1.0-hi, 1.0-lo); | ||
1098 | 155 | |||
1099 | 156 | painter->setPen(color); | ||
1100 | 157 | switch (m_alignment) { | ||
1101 | 158 | case Qt::AlignBottom : | ||
1102 | 159 | painter->drawLine( | ||
1103 | 160 | x, m_waveformRenderer->getHeight(), | ||
1104 | 161 | x, m_waveformRenderer->getHeight() - (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1]))); | ||
1105 | 162 | break; | ||
1106 | 163 | case Qt::AlignTop : | ||
1107 | 164 | painter->drawLine( | ||
1108 | 165 | x, 0, | ||
1109 | 166 | x, (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1]))); | ||
1110 | 167 | break; | ||
1111 | 168 | default : | ||
1112 | 169 | painter->drawLine( | ||
1113 | 170 | x, (int)(halfHeight-heightFactor*(float)maxAll[0]), | ||
1114 | 171 | x, (int)(halfHeight+heightFactor*(float)maxAll[1])); | ||
1115 | 172 | } | ||
1116 | 173 | } | ||
1117 | 174 | } | ||
1118 | 175 | |||
1119 | 176 | painter->restore(); | ||
1120 | 177 | } | ||
1121 | 0 | 178 | ||
1122 | === removed file 'mixxx/src/waveform/renderers/waveformrendererhsv.cpp' | |||
1123 | --- mixxx/src/waveform/renderers/waveformrendererhsv.cpp 2013-01-16 21:03:36 +0000 | |||
1124 | +++ mixxx/src/waveform/renderers/waveformrendererhsv.cpp 1970-01-01 00:00:00 +0000 | |||
1125 | @@ -1,177 +0,0 @@ | |||
1126 | 1 | #include "waveformrendererhsv.h" | ||
1127 | 2 | |||
1128 | 3 | #include "waveformwidgetrenderer.h" | ||
1129 | 4 | #include "waveform/waveform.h" | ||
1130 | 5 | #include "waveform/waveformwidgetfactory.h" | ||
1131 | 6 | |||
1132 | 7 | #include "widget/wskincolor.h" | ||
1133 | 8 | #include "trackinfoobject.h" | ||
1134 | 9 | #include "widget/wwidget.h" | ||
1135 | 10 | |||
1136 | 11 | #include "defs.h" | ||
1137 | 12 | |||
1138 | 13 | #include "controlobjectthreadmain.h" | ||
1139 | 14 | |||
1140 | 15 | WaveformRendererHSV::WaveformRendererHSV( | ||
1141 | 16 | WaveformWidgetRenderer* waveformWidgetRenderer) | ||
1142 | 17 | : WaveformRendererSignalBase( waveformWidgetRenderer) { | ||
1143 | 18 | } | ||
1144 | 19 | |||
1145 | 20 | WaveformRendererHSV::~WaveformRendererHSV() { | ||
1146 | 21 | } | ||
1147 | 22 | |||
1148 | 23 | void WaveformRendererHSV::onSetup(const QDomNode& node) { | ||
1149 | 24 | Q_UNUSED(node); | ||
1150 | 25 | } | ||
1151 | 26 | |||
1152 | 27 | void WaveformRendererHSV::draw(QPainter* painter, | ||
1153 | 28 | QPaintEvent* /*event*/) { | ||
1154 | 29 | const TrackPointer trackInfo = m_waveformRenderer->getTrackInfo(); | ||
1155 | 30 | if (!trackInfo) { | ||
1156 | 31 | return; | ||
1157 | 32 | } | ||
1158 | 33 | |||
1159 | 34 | const Waveform* waveform = trackInfo->getWaveform(); | ||
1160 | 35 | if (waveform == NULL) { | ||
1161 | 36 | return; | ||
1162 | 37 | } | ||
1163 | 38 | |||
1164 | 39 | const int dataSize = waveform->getDataSize(); | ||
1165 | 40 | if (dataSize <= 1) { | ||
1166 | 41 | return; | ||
1167 | 42 | } | ||
1168 | 43 | |||
1169 | 44 | const WaveformData* data = waveform->data(); | ||
1170 | 45 | if (data == NULL) { | ||
1171 | 46 | return; | ||
1172 | 47 | } | ||
1173 | 48 | |||
1174 | 49 | painter->save(); | ||
1175 | 50 | painter->setRenderHints(QPainter::Antialiasing, false); | ||
1176 | 51 | painter->setRenderHints(QPainter::HighQualityAntialiasing, false); | ||
1177 | 52 | painter->setRenderHints(QPainter::SmoothPixmapTransform, false); | ||
1178 | 53 | painter->setWorldMatrixEnabled(false); | ||
1179 | 54 | painter->resetTransform(); | ||
1180 | 55 | |||
1181 | 56 | const double firstVisualIndex = m_waveformRenderer->getFirstDisplayedPosition() * dataSize; | ||
1182 | 57 | const double lastVisualIndex = m_waveformRenderer->getLastDisplayedPosition() * dataSize; | ||
1183 | 58 | |||
1184 | 59 | const double offset = firstVisualIndex; | ||
1185 | 60 | |||
1186 | 61 | // Represents the # of waveform data points per horizontal pixel. | ||
1187 | 62 | const double gain = (lastVisualIndex - firstVisualIndex) / | ||
1188 | 63 | (double)m_waveformRenderer->getWidth(); | ||
1189 | 64 | |||
1190 | 65 | float allGain(1.0); | ||
1191 | 66 | allGain = m_waveformRenderer->getGain(); | ||
1192 | 67 | |||
1193 | 68 | WaveformWidgetFactory* factory = WaveformWidgetFactory::instance(); | ||
1194 | 69 | allGain *= factory->getVisualGain(::WaveformWidgetFactory::All); | ||
1195 | 70 | |||
1196 | 71 | // Save HSV of waveform color | ||
1197 | 72 | double h,s,v; | ||
1198 | 73 | |||
1199 | 74 | // Get base color of waveform in the HSV format (s and v isn't use) | ||
1200 | 75 | m_pColors->getLowColor().getHsvF(&h,&s,&v); | ||
1201 | 76 | |||
1202 | 77 | QColor color; | ||
1203 | 78 | float lo, hi, total; | ||
1204 | 79 | |||
1205 | 80 | const float halfHeight = (float)m_waveformRenderer->getHeight()/2.0; | ||
1206 | 81 | |||
1207 | 82 | const float heightFactor = allGain*halfHeight/255.0; | ||
1208 | 83 | |||
1209 | 84 | //draw reference line | ||
1210 | 85 | painter->setPen(m_axesColor); | ||
1211 | 86 | painter->drawLine(0,halfHeight,m_waveformRenderer->getWidth(),halfHeight); | ||
1212 | 87 | |||
1213 | 88 | for (int x = 0; x < m_waveformRenderer->getWidth(); ++x) { | ||
1214 | 89 | // Width of the x position in visual indices. | ||
1215 | 90 | const double xSampleWidth = gain * x; | ||
1216 | 91 | |||
1217 | 92 | // Effective visual index of x | ||
1218 | 93 | const double xVisualSampleIndex = xSampleWidth + offset; | ||
1219 | 94 | |||
1220 | 95 | // Our current pixel (x) corresponds to a number of visual samples | ||
1221 | 96 | // (visualSamplerPerPixel) in our waveform object. We take the max of | ||
1222 | 97 | // all the data points on either side of xVisualSampleIndex within a | ||
1223 | 98 | // window of 'maxSamplingRange' visual samples to measure the maximum | ||
1224 | 99 | // data point contained by this pixel. | ||
1225 | 100 | double maxSamplingRange = gain / 2.0; | ||
1226 | 101 | |||
1227 | 102 | // Since xVisualSampleIndex is in visual-samples (e.g. R,L,R,L) we want | ||
1228 | 103 | // to check +/- maxSamplingRange frames, not samples. To do this, divide | ||
1229 | 104 | // xVisualSampleIndex by 2. Since frames indices are integers, we round | ||
1230 | 105 | // to the nearest integer by adding 0.5 before casting to int. | ||
1231 | 106 | int visualFrameStart = int(xVisualSampleIndex / 2.0 - maxSamplingRange + 0.5); | ||
1232 | 107 | int visualFrameStop = int(xVisualSampleIndex / 2.0 + maxSamplingRange + 0.5); | ||
1233 | 108 | const int lastVisualFrame = dataSize / 2 - 1; | ||
1234 | 109 | |||
1235 | 110 | // We now know that some subset of [visualFrameStart, visualFrameStop] | ||
1236 | 111 | // lies within the valid range of visual frames. Clamp | ||
1237 | 112 | // visualFrameStart/Stop to within [0, lastVisualFrame]. | ||
1238 | 113 | visualFrameStart = math_max(math_min(lastVisualFrame, visualFrameStart), 0); | ||
1239 | 114 | visualFrameStop = math_max(math_min(lastVisualFrame, visualFrameStop), 0); | ||
1240 | 115 | |||
1241 | 116 | int visualIndexStart = visualFrameStart * 2; | ||
1242 | 117 | int visualIndexStop = visualFrameStop * 2; | ||
1243 | 118 | |||
1244 | 119 | int maxLow[2] = {0, 0}; | ||
1245 | 120 | int maxHigh[2] = {0, 0}; | ||
1246 | 121 | int maxMid[2] = {0, 0}; | ||
1247 | 122 | int maxAll[2] = {0, 0}; | ||
1248 | 123 | |||
1249 | 124 | for (int i = visualIndexStart; | ||
1250 | 125 | i >= 0 && i + 1 < dataSize && i + 1 <= visualIndexStop; i += 2) { | ||
1251 | 126 | const WaveformData& waveformData = *(data + i); | ||
1252 | 127 | const WaveformData& waveformDataNext = *(data + i + 1); | ||
1253 | 128 | maxLow[0] = math_max(maxLow[0], (int)waveformData.filtered.low); | ||
1254 | 129 | maxLow[1] = math_max(maxLow[1], (int)waveformDataNext.filtered.low); | ||
1255 | 130 | maxMid[0] = math_max(maxMid[0], (int)waveformData.filtered.mid); | ||
1256 | 131 | maxMid[1] = math_max(maxMid[1], (int)waveformDataNext.filtered.mid); | ||
1257 | 132 | maxHigh[0] = math_max(maxHigh[0], (int)waveformData.filtered.high); | ||
1258 | 133 | maxHigh[1] = math_max(maxHigh[1], (int)waveformDataNext.filtered.high); | ||
1259 | 134 | maxAll[0] = math_max( maxAll[0], (int)waveformData.filtered.all); | ||
1260 | 135 | maxAll[1] = math_max( maxAll[1], (int)waveformDataNext.filtered.all); | ||
1261 | 136 | } | ||
1262 | 137 | |||
1263 | 138 | if( maxAll[0] && maxAll[1] ) { | ||
1264 | 139 | // Calculate sum, to normalize | ||
1265 | 140 | // Also multiply on 1.2 to prevent very dark or light color | ||
1266 | 141 | total = (maxLow[0] + maxLow[1] + maxMid[0] + maxMid[1] + maxHigh[0] + maxHigh[1]) * 1.2; | ||
1267 | 142 | |||
1268 | 143 | // prevent division by zero | ||
1269 | 144 | if( total > 0 ) | ||
1270 | 145 | { | ||
1271 | 146 | // Normalize low and high (mid not need, because it not change the color) | ||
1272 | 147 | lo = (maxLow[0] + maxLow[1]) / total; | ||
1273 | 148 | hi = (maxHigh[0] + maxHigh[1]) / total; | ||
1274 | 149 | } | ||
1275 | 150 | else | ||
1276 | 151 | lo = hi = 0.0; | ||
1277 | 152 | |||
1278 | 153 | // Set color | ||
1279 | 154 | color.setHsvF(h, 1.0-hi, 1.0-lo); | ||
1280 | 155 | |||
1281 | 156 | painter->setPen(color); | ||
1282 | 157 | switch (m_alignment) { | ||
1283 | 158 | case Qt::AlignBottom : | ||
1284 | 159 | painter->drawLine( | ||
1285 | 160 | x, m_waveformRenderer->getHeight(), | ||
1286 | 161 | x, m_waveformRenderer->getHeight() - (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1]))); | ||
1287 | 162 | break; | ||
1288 | 163 | case Qt::AlignTop : | ||
1289 | 164 | painter->drawLine( | ||
1290 | 165 | x, 0, | ||
1291 | 166 | x, (int)(heightFactor*(float)math_max(maxAll[0],maxAll[1]))); | ||
1292 | 167 | break; | ||
1293 | 168 | default : | ||
1294 | 169 | painter->drawLine( | ||
1295 | 170 | x, (int)(halfHeight-heightFactor*(float)maxAll[0]), | ||
1296 | 171 | x, (int)(halfHeight+heightFactor*(float)maxAll[1])); | ||
1297 | 172 | } | ||
1298 | 173 | } | ||
1299 | 174 | } | ||
1300 | 175 | |||
1301 | 176 | painter->restore(); | ||
1302 | 177 | } | ||
1303 | 178 | 0 | ||
1304 | === added file 'mixxx/src/waveform/renderers/waveformrendererhsv.h' | |||
1305 | --- mixxx/src/waveform/renderers/waveformrendererhsv.h 1970-01-01 00:00:00 +0000 | |||
1306 | +++ mixxx/src/waveform/renderers/waveformrendererhsv.h 2013-05-01 22:08:27 +0000 | |||
1307 | @@ -0,0 +1,21 @@ | |||
1308 | 1 | #ifndef WAVEFORMRENDERERHSV_H | ||
1309 | 2 | #define WAVEFORMRENDERERHSV_H | ||
1310 | 3 | |||
1311 | 4 | #include "waveformrenderersignalbase.h" | ||
1312 | 5 | #include "util.h" | ||
1313 | 6 | |||
1314 | 7 | class WaveformRendererHSV : public WaveformRendererSignalBase { | ||
1315 | 8 | public: | ||
1316 | 9 | explicit WaveformRendererHSV( | ||
1317 | 10 | WaveformWidgetRenderer* waveformWidget); | ||
1318 | 11 | virtual ~WaveformRendererHSV(); | ||
1319 | 12 | |||
1320 | 13 | virtual void onSetup(const QDomNode& node); | ||
1321 | 14 | |||
1322 | 15 | virtual void draw(QPainter* painter, QPaintEvent* event); | ||
1323 | 16 | |||
1324 | 17 | private: | ||
1325 | 18 | DISALLOW_COPY_AND_ASSIGN(WaveformRendererHSV); | ||
1326 | 19 | }; | ||
1327 | 20 | |||
1328 | 21 | #endif // WAVEFORMRENDERERFILTEREDSIGNAL_H | ||
1329 | 0 | 22 | ||
1330 | === removed file 'mixxx/src/waveform/renderers/waveformrendererhsv.h' | |||
1331 | --- mixxx/src/waveform/renderers/waveformrendererhsv.h 2012-12-14 01:26:04 +0000 | |||
1332 | +++ mixxx/src/waveform/renderers/waveformrendererhsv.h 1970-01-01 00:00:00 +0000 | |||
1333 | @@ -1,21 +0,0 @@ | |||
1334 | 1 | #ifndef WAVEFORMRENDERERHSV_H | ||
1335 | 2 | #define WAVEFORMRENDERERHSV_H | ||
1336 | 3 | |||
1337 | 4 | #include "waveformrenderersignalbase.h" | ||
1338 | 5 | #include "util.h" | ||
1339 | 6 | |||
1340 | 7 | class WaveformRendererHSV : public WaveformRendererSignalBase { | ||
1341 | 8 | public: | ||
1342 | 9 | explicit WaveformRendererHSV( | ||
1343 | 10 | WaveformWidgetRenderer* waveformWidget); | ||
1344 | 11 | virtual ~WaveformRendererHSV(); | ||
1345 | 12 | |||
1346 | 13 | virtual void onSetup(const QDomNode& node); | ||
1347 | 14 | |||
1348 | 15 | virtual void draw(QPainter* painter, QPaintEvent* event); | ||
1349 | 16 | |||
1350 | 17 | private: | ||
1351 | 18 | DISALLOW_COPY_AND_ASSIGN(WaveformRendererHSV); | ||
1352 | 19 | }; | ||
1353 | 20 | |||
1354 | 21 | #endif // WAVEFORMRENDERERFILTEREDSIGNAL_H | ||
1355 | 22 | 0 | ||
1356 | === modified file 'mixxx/src/waveform/renderers/waveformrendererpreroll.cpp' | |||
1357 | --- mixxx/src/waveform/renderers/waveformrendererpreroll.cpp 2012-11-20 21:24:37 +0000 | |||
1358 | +++ mixxx/src/waveform/renderers/waveformrendererpreroll.cpp 2013-05-01 22:08:27 +0000 | |||
1359 | @@ -29,14 +29,13 @@ | |||
1360 | 29 | if (!track) { | 29 | if (!track) { |
1361 | 30 | return; | 30 | return; |
1362 | 31 | } | 31 | } |
1363 | 32 | const Waveform* waveform = track->getWaveform(); | ||
1364 | 33 | double samplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel(); | 32 | double samplesPerPixel = m_waveformRenderer->getVisualSamplePerPixel(); |
1365 | 34 | double numberOfSamples = m_waveformRenderer->getWidth() * samplesPerPixel; | 33 | double numberOfSamples = m_waveformRenderer->getWidth() * samplesPerPixel; |
1366 | 35 | 34 | ||
1367 | 36 | // TODO (vRince) not really accurate since waveform size une visual reasampling and | 35 | // TODO (vRince) not really accurate since waveform size une visual reasampling and |
1368 | 37 | // have two mores samples to hold the complete visual data | 36 | // have two mores samples to hold the complete visual data |
1371 | 38 | int currentPosition = m_waveformRenderer->getPlayPos() * waveform->getDataSize(); | 37 | int currentPosition = m_waveformRenderer->getPlayPosVSample(); |
1372 | 39 | m_waveformRenderer->regulateVisualSample(currentPosition); | 38 | // m_waveformRenderer->regulateVisualSample(currentPosition); |
1373 | 40 | 39 | ||
1374 | 41 | // Some of the pre-roll is on screen. Draw little triangles to indicate | 40 | // Some of the pre-roll is on screen. Draw little triangles to indicate |
1375 | 42 | // where the pre-roll is located. | 41 | // where the pre-roll is located. |
1376 | @@ -47,6 +46,9 @@ | |||
1377 | 47 | const float halfPolyHeight = m_waveformRenderer->getHeight()/5.0; | 46 | const float halfPolyHeight = m_waveformRenderer->getHeight()/5.0; |
1378 | 48 | 47 | ||
1379 | 49 | painter->save(); | 48 | painter->save(); |
1380 | 49 | painter->setRenderHint(QPainter::Antialiasing); | ||
1381 | 50 | //painter->setRenderHint(QPainter::HighQualityAntialiasing); | ||
1382 | 51 | //painter->setBackgroundMode(Qt::TransparentMode); | ||
1383 | 50 | painter->setWorldMatrixEnabled(false); | 52 | painter->setWorldMatrixEnabled(false); |
1384 | 51 | painter->setPen(QPen(QBrush(m_color), 1)); | 53 | painter->setPen(QPen(QBrush(m_color), 1)); |
1385 | 52 | QPolygonF polygon; | 54 | QPolygonF polygon; |
1386 | 53 | 55 | ||
1387 | === modified file 'mixxx/src/waveform/renderers/waveformrendermark.cpp' | |||
1388 | --- mixxx/src/waveform/renderers/waveformrendermark.cpp 2013-03-27 21:32:51 +0000 | |||
1389 | +++ mixxx/src/waveform/renderers/waveformrendermark.cpp 2013-05-01 22:08:27 +0000 | |||
1390 | @@ -48,8 +48,8 @@ | |||
1391 | 48 | } | 48 | } |
1392 | 49 | 49 | ||
1393 | 50 | int samplePosition = mark.m_pointControl->get(); | 50 | int samplePosition = mark.m_pointControl->get(); |
1396 | 51 | if (samplePosition >= 0.0) { | 51 | if (samplePosition > 0.0) { |
1397 | 52 | m_waveformRenderer->regulateVisualSample(samplePosition); | 52 | //m_waveformRenderer->regulateVisualSample(samplePosition); |
1398 | 53 | double currentMarkPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(samplePosition); | 53 | double currentMarkPoint = m_waveformRenderer->transformSampleIndexInRendererWorld(samplePosition); |
1399 | 54 | 54 | ||
1400 | 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 ! |
1401 | 56 | 56 | ||
1402 | === modified file 'mixxx/src/waveform/renderers/waveformrendermarkrange.cpp' | |||
1403 | --- mixxx/src/waveform/renderers/waveformrendermarkrange.cpp 2013-01-31 19:48:57 +0000 | |||
1404 | +++ mixxx/src/waveform/renderers/waveformrendermarkrange.cpp 2013-05-01 22:08:27 +0000 | |||
1405 | @@ -58,10 +58,10 @@ | |||
1406 | 58 | int startSample = markRange.start(); | 58 | int startSample = markRange.start(); |
1407 | 59 | int endSample = markRange.end(); | 59 | int endSample = markRange.end(); |
1408 | 60 | 60 | ||
1410 | 61 | m_waveformRenderer->regulateVisualSample(startSample); | 61 | //m_waveformRenderer->regulateVisualSample(startSample); |
1411 | 62 | double startPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(startSample); | 62 | double startPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(startSample); |
1412 | 63 | 63 | ||
1414 | 64 | m_waveformRenderer->regulateVisualSample(endSample); | 64 | //m_waveformRenderer->regulateVisualSample(endSample); |
1415 | 65 | double endPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(endSample); | 65 | double endPosition = m_waveformRenderer->transformSampleIndexInRendererWorld(endSample); |
1416 | 66 | 66 | ||
1417 | 67 | //range not in the current display | 67 | //range not in the current display |
1418 | 68 | 68 | ||
1419 | === modified file 'mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp' | |||
1420 | --- mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp 2013-01-31 21:53:32 +0000 | |||
1421 | +++ mixxx/src/waveform/renderers/waveformwidgetrenderer.cpp 2013-05-01 22:08:27 +0000 | |||
1422 | @@ -6,56 +6,49 @@ | |||
1423 | 6 | #include "controlobjectthreadmain.h" | 6 | #include "controlobjectthreadmain.h" |
1424 | 7 | #include "controlobject.h" | 7 | #include "controlobject.h" |
1425 | 8 | #include "defs.h" | 8 | #include "defs.h" |
1426 | 9 | #include "visualplayposition.h" | ||
1427 | 9 | #include "mathstuff.h" | 10 | #include "mathstuff.h" |
1428 | 10 | 11 | ||
1429 | 12 | #include "util/performancetimer.h" | ||
1430 | 13 | |||
1431 | 14 | #include <QPainter> | ||
1432 | 15 | |||
1433 | 11 | const int WaveformWidgetRenderer::s_waveformMinZoom = 1; | 16 | const int WaveformWidgetRenderer::s_waveformMinZoom = 1; |
1434 | 12 | const int WaveformWidgetRenderer::s_waveformMaxZoom = 6; | 17 | const int WaveformWidgetRenderer::s_waveformMaxZoom = 6; |
1435 | 13 | 18 | ||
1454 | 14 | WaveformWidgetRenderer::WaveformWidgetRenderer() { | 19 | WaveformWidgetRenderer::WaveformWidgetRenderer( const char* group) |
1455 | 15 | m_playPosControlObject = NULL; | 20 | : m_group(group), |
1456 | 16 | m_rateControlObject = NULL; | 21 | m_trackInfoObject(0), |
1457 | 17 | m_rateRangeControlObject = NULL; | 22 | m_height(-1), |
1458 | 18 | m_rateDirControlObject = NULL; | 23 | m_width(-1), |
1459 | 19 | m_gainControlObject = NULL; | 24 | |
1460 | 20 | m_trackSamplesControlObject = NULL; | 25 | m_firstDisplayedPosition(0.0), |
1461 | 21 | 26 | m_lastDisplayedPosition(0.0), | |
1462 | 22 | #ifdef WAVEFORMWIDGETRENDERER_DEBUG | 27 | m_rendererTransformationOffset(0.0), |
1463 | 23 | m_timer = NULL; | 28 | m_rendererTransformationGain(0.0), |
1464 | 24 | #endif | 29 | |
1465 | 25 | } | 30 | m_zoomFactor(1.0), |
1466 | 26 | 31 | m_rateAdjust(0.0), | |
1467 | 27 | WaveformWidgetRenderer::WaveformWidgetRenderer( const char* group) : | 32 | m_visualSamplePerPixel(1.0), |
1468 | 28 | m_group(group), | 33 | m_audioSamplePerPixel(1.0), |
1469 | 29 | m_trackInfoObject(0), | 34 | |
1470 | 30 | m_height(-1), | 35 | // Really create some to manage those; |
1471 | 31 | m_width(-1) { | 36 | m_visualPlayPosition(NULL), |
1472 | 37 | m_playPos(-1), | ||
1473 | 38 | m_playPosVSample(0), | ||
1474 | 39 | m_rateControlObject(NULL), | ||
1475 | 40 | m_rate(0.0), | ||
1476 | 41 | m_rateRangeControlObject(NULL), | ||
1477 | 42 | m_rateRange(0.0), | ||
1478 | 43 | m_rateDirControlObject(NULL), | ||
1479 | 44 | m_rateDir(0.0), | ||
1480 | 45 | m_gainControlObject(NULL), | ||
1481 | 46 | m_gain(1.0), | ||
1482 | 47 | m_trackSamplesControlObject(NULL), | ||
1483 | 48 | m_trackSamples(0.0) { | ||
1484 | 49 | |||
1485 | 32 | //qDebug() << "WaveformWidgetRenderer"; | 50 | //qDebug() << "WaveformWidgetRenderer"; |
1486 | 33 | 51 | ||
1487 | 34 | m_firstDisplayedPosition = 0.0; | ||
1488 | 35 | m_lastDisplayedPosition = 0.0; | ||
1489 | 36 | m_rendererTransformationOffset = 0.0; | ||
1490 | 37 | m_rendererTransformationGain = 0.0; | ||
1491 | 38 | |||
1492 | 39 | m_zoomFactor = 1.0; | ||
1493 | 40 | m_rateAdjust = 0.0; | ||
1494 | 41 | m_visualSamplePerPixel = 1.0; | ||
1495 | 42 | m_audioSamplePerPixel = 1.0; | ||
1496 | 43 | |||
1497 | 44 | // Really create some to manage those | ||
1498 | 45 | m_playPosControlObject = NULL; | ||
1499 | 46 | m_playPos = 0.0; | ||
1500 | 47 | m_rateControlObject = NULL; | ||
1501 | 48 | m_rate = 0.0; | ||
1502 | 49 | m_rateRangeControlObject = NULL; | ||
1503 | 50 | m_rateRange = 0.0; | ||
1504 | 51 | m_rateDirControlObject = NULL; | ||
1505 | 52 | m_rateDir = 0.0; | ||
1506 | 53 | m_gainControlObject = NULL; | ||
1507 | 54 | m_gain = 1.0; | ||
1508 | 55 | m_trackSamplesControlObject = NULL; | ||
1509 | 56 | m_trackSamples = -1.0; | ||
1510 | 57 | |||
1511 | 58 | |||
1512 | 59 | #ifdef WAVEFORMWIDGETRENDERER_DEBUG | 52 | #ifdef WAVEFORMWIDGETRENDERER_DEBUG |
1513 | 60 | m_timer = new QTime(); | 53 | m_timer = new QTime(); |
1514 | 61 | currentFrame = 0; | 54 | currentFrame = 0; |
1515 | @@ -74,7 +67,6 @@ | |||
1516 | 74 | for( int i = 0; i < m_rendererStack.size(); ++i) | 67 | for( int i = 0; i < m_rendererStack.size(); ++i) |
1517 | 75 | delete m_rendererStack[i]; | 68 | delete m_rendererStack[i]; |
1518 | 76 | 69 | ||
1519 | 77 | delete m_playPosControlObject; | ||
1520 | 78 | delete m_rateControlObject; | 70 | delete m_rateControlObject; |
1521 | 79 | delete m_rateRangeControlObject; | 71 | delete m_rateRangeControlObject; |
1522 | 80 | delete m_rateDirControlObject; | 72 | delete m_rateDirControlObject; |
1523 | @@ -89,9 +81,8 @@ | |||
1524 | 89 | bool WaveformWidgetRenderer::init() { | 81 | bool WaveformWidgetRenderer::init() { |
1525 | 90 | 82 | ||
1526 | 91 | //qDebug() << "WaveformWidgetRenderer::init"; | 83 | //qDebug() << "WaveformWidgetRenderer::init"; |
1527 | 84 | m_visualPlayPosition = VisualPlayPosition::getVisualPlayPosition(m_group); | ||
1528 | 92 | 85 | ||
1529 | 93 | m_playPosControlObject = new ControlObjectThreadMain( | ||
1530 | 94 | ControlObject::getControl( ConfigKey(m_group, "visual_playposition"))); | ||
1531 | 95 | m_rateControlObject = new ControlObjectThreadMain( | 86 | m_rateControlObject = new ControlObjectThreadMain( |
1532 | 96 | ControlObject::getControl( ConfigKey(m_group, "rate"))); | 87 | ControlObject::getControl( ConfigKey(m_group, "rate"))); |
1533 | 97 | m_rateRangeControlObject = new ControlObjectThreadMain( | 88 | m_rateRangeControlObject = new ControlObjectThreadMain( |
1534 | @@ -111,7 +102,7 @@ | |||
1535 | 111 | return true; | 102 | return true; |
1536 | 112 | } | 103 | } |
1537 | 113 | 104 | ||
1539 | 114 | void WaveformWidgetRenderer::onPreRender() { | 105 | void WaveformWidgetRenderer::onPreRender(VSyncThread* vsyncThread) { |
1540 | 115 | // For a valid track to render we need | 106 | // For a valid track to render we need |
1541 | 116 | m_trackSamples = m_trackSamplesControlObject->get(); | 107 | m_trackSamples = m_trackSamplesControlObject->get(); |
1542 | 117 | if (m_trackSamples <= 0.0) { | 108 | if (m_trackSamples <= 0.0) { |
1543 | @@ -141,7 +132,7 @@ | |||
1544 | 141 | m_audioSamplePerPixel = 0.0; | 132 | m_audioSamplePerPixel = 0.0; |
1545 | 142 | } | 133 | } |
1546 | 143 | 134 | ||
1548 | 144 | m_playPos = m_playPosControlObject->get(); | 135 | m_playPos = m_visualPlayPosition->getAt(vsyncThread); |
1549 | 145 | // m_playPos = -1 happens, when a new track is in buffer but m_visualPlayPosition was not updated | 136 | // m_playPos = -1 happens, when a new track is in buffer but m_visualPlayPosition was not updated |
1550 | 146 | 137 | ||
1551 | 147 | if (m_audioSamplePerPixel && m_playPos != -1) { | 138 | if (m_audioSamplePerPixel && m_playPos != -1) { |
1552 | @@ -153,7 +144,9 @@ | |||
1553 | 153 | double displayedLengthHalf = static_cast<double>(m_width) / trackPixel / 2.0; | 144 | double displayedLengthHalf = static_cast<double>(m_width) / trackPixel / 2.0; |
1554 | 154 | // Avoid pixel jitter in play position by rounding to the nearest track | 145 | // Avoid pixel jitter in play position by rounding to the nearest track |
1555 | 155 | // pixel. | 146 | // pixel. |
1557 | 156 | m_playPos = round(m_playPosControlObject->get() * trackPixel) / trackPixel; | 147 | m_playPos = round(m_playPos * trackPixel)/(double)trackPixel; // Avoid pixel jitter in play position |
1558 | 148 | m_playPosVSample = m_playPos * m_trackInfoObject->getWaveform()->getDataSize(); | ||
1559 | 149 | |||
1560 | 157 | m_firstDisplayedPosition = m_playPos - displayedLengthHalf; | 150 | m_firstDisplayedPosition = m_playPos - displayedLengthHalf; |
1561 | 158 | m_lastDisplayedPosition = m_playPos + displayedLengthHalf; | 151 | m_lastDisplayedPosition = m_playPos + displayedLengthHalf; |
1562 | 159 | m_rendererTransformationOffset = - m_firstDisplayedPosition; | 152 | m_rendererTransformationOffset = - m_firstDisplayedPosition; |
1563 | @@ -181,6 +174,9 @@ | |||
1564 | 181 | m_lastSystemFrameTime = m_timer->restart(); | 174 | m_lastSystemFrameTime = m_timer->restart(); |
1565 | 182 | #endif | 175 | #endif |
1566 | 183 | 176 | ||
1567 | 177 | // PerformanceTimer timer; | ||
1568 | 178 | // timer.start(); | ||
1569 | 179 | |||
1570 | 184 | //not ready to display need to wait until track initialization is done | 180 | //not ready to display need to wait until track initialization is done |
1571 | 185 | //draw only first is stack (background) | 181 | //draw only first is stack (background) |
1572 | 186 | int stackSize = m_rendererStack.size(); | 182 | int stackSize = m_rendererStack.size(); |
1573 | @@ -191,7 +187,9 @@ | |||
1574 | 191 | return; | 187 | return; |
1575 | 192 | } else { | 188 | } else { |
1576 | 193 | for (int i = 0; i < stackSize; i++) { | 189 | for (int i = 0; i < stackSize; i++) { |
1577 | 190 | // qDebug() << i << " a " << timer.restart(); | ||
1578 | 194 | m_rendererStack.at(i)->draw(painter, event); | 191 | m_rendererStack.at(i)->draw(painter, event); |
1579 | 192 | // qDebug() << i << " e " << timer.restart(); | ||
1580 | 195 | } | 193 | } |
1581 | 196 | 194 | ||
1582 | 197 | painter->setPen(m_colors.getPlayPosColor()); | 195 | painter->setPen(m_colors.getPlayPosColor()); |
1583 | @@ -215,7 +213,8 @@ | |||
1584 | 215 | QString::number(m_lastFrameTime).rightJustified(2,'0') + "(" + | 213 | QString::number(m_lastFrameTime).rightJustified(2,'0') + "(" + |
1585 | 216 | QString::number(frameMax).rightJustified(2,'0') + ")" + | 214 | QString::number(frameMax).rightJustified(2,'0') + ")" + |
1586 | 217 | QString::number(m_lastSystemFrameTime) + "(" + | 215 | QString::number(m_lastSystemFrameTime) + "(" + |
1588 | 218 | QString::number(systemMax) + ")"); | 216 | QString::number(systemMax) + ")" + |
1589 | 217 | QString::number(realtimeError)); | ||
1590 | 219 | 218 | ||
1591 | 220 | painter->drawText(1,m_height-1, | 219 | painter->drawText(1,m_height-1, |
1592 | 221 | QString::number(m_playPos) + " [" + | 220 | QString::number(m_playPos) + " [" + |
1593 | @@ -234,6 +233,7 @@ | |||
1594 | 234 | m_lastFramesTime[currentFrame] = m_lastFrameTime; | 233 | m_lastFramesTime[currentFrame] = m_lastFrameTime; |
1595 | 235 | #endif | 234 | #endif |
1596 | 236 | 235 | ||
1597 | 236 | // qDebug() << "draw() ende" << timer.restart(); | ||
1598 | 237 | } | 237 | } |
1599 | 238 | 238 | ||
1600 | 239 | void WaveformWidgetRenderer::resize( int width, int height) { | 239 | void WaveformWidgetRenderer::resize( int width, int height) { |
1601 | 240 | 240 | ||
1602 | === modified file 'mixxx/src/waveform/renderers/waveformwidgetrenderer.h' | |||
1603 | --- mixxx/src/waveform/renderers/waveformwidgetrenderer.h 2013-01-31 21:53:32 +0000 | |||
1604 | +++ mixxx/src/waveform/renderers/waveformwidgetrenderer.h 2013-05-01 22:08:27 +0000 | |||
1605 | @@ -15,6 +15,8 @@ | |||
1606 | 15 | 15 | ||
1607 | 16 | class TrackInfoObject; | 16 | class TrackInfoObject; |
1608 | 17 | class ControlObjectThreadMain; | 17 | class ControlObjectThreadMain; |
1609 | 18 | class VisualPlayPosition; | ||
1610 | 19 | class VSyncThread; | ||
1611 | 18 | 20 | ||
1612 | 19 | class WaveformWidgetRenderer { | 21 | class WaveformWidgetRenderer { |
1613 | 20 | public: | 22 | public: |
1614 | @@ -29,7 +31,7 @@ | |||
1615 | 29 | virtual bool onInit() {return true;} | 31 | virtual bool onInit() {return true;} |
1616 | 30 | 32 | ||
1617 | 31 | void setup(const QDomNode& node); | 33 | void setup(const QDomNode& node); |
1619 | 32 | void onPreRender(); | 34 | void onPreRender(VSyncThread* vsyncThread); |
1620 | 33 | void draw(QPainter* painter, QPaintEvent* event); | 35 | void draw(QPainter* painter, QPaintEvent* event); |
1621 | 34 | 36 | ||
1622 | 35 | const char* getGroup() const { return m_group;} | 37 | const char* getGroup() const { return m_group;} |
1623 | @@ -56,6 +58,7 @@ | |||
1624 | 56 | double transformPositionInRendererWorld(double position) const; | 58 | double transformPositionInRendererWorld(double position) const; |
1625 | 57 | 59 | ||
1626 | 58 | double getPlayPos() const { return m_playPos;} | 60 | double getPlayPos() const { return m_playPos;} |
1627 | 61 | double getPlayPosVSample() const { return m_playPosVSample;} | ||
1628 | 59 | double getZoomFactor() const { return m_zoomFactor;} | 62 | double getZoomFactor() const { return m_zoomFactor;} |
1629 | 60 | double getRateAdjust() const { return m_rateAdjust;} | 63 | double getRateAdjust() const { return m_rateAdjust;} |
1630 | 61 | double getGain() const { return m_gain;} | 64 | double getGain() const { return m_gain;} |
1631 | @@ -78,7 +81,7 @@ | |||
1632 | 78 | protected: | 81 | protected: |
1633 | 79 | const char* m_group; | 82 | const char* m_group; |
1634 | 80 | TrackPointer m_trackInfoObject; | 83 | TrackPointer m_trackInfoObject; |
1636 | 81 | QVector<WaveformRendererAbstract*> m_rendererStack; | 84 | QList<WaveformRendererAbstract*> m_rendererStack; |
1637 | 82 | int m_height; | 85 | int m_height; |
1638 | 83 | int m_width; | 86 | int m_width; |
1639 | 84 | WaveformSignalColors m_colors; | 87 | WaveformSignalColors m_colors; |
1640 | @@ -95,8 +98,9 @@ | |||
1641 | 95 | 98 | ||
1642 | 96 | //TODO: vRince create some class to manage control/value | 99 | //TODO: vRince create some class to manage control/value |
1643 | 97 | //ControlConnection | 100 | //ControlConnection |
1645 | 98 | ControlObjectThreadMain* m_playPosControlObject; | 101 | VisualPlayPosition* m_visualPlayPosition; |
1646 | 99 | double m_playPos; | 102 | double m_playPos; |
1647 | 103 | int m_playPosVSample; | ||
1648 | 100 | ControlObjectThreadMain* m_rateControlObject; | 104 | ControlObjectThreadMain* m_rateControlObject; |
1649 | 101 | double m_rate; | 105 | double m_rate; |
1650 | 102 | ControlObjectThreadMain* m_rateRangeControlObject; | 106 | ControlObjectThreadMain* m_rateRangeControlObject; |
1651 | @@ -117,7 +121,6 @@ | |||
1652 | 117 | int currentFrame; | 121 | int currentFrame; |
1653 | 118 | #endif | 122 | #endif |
1654 | 119 | 123 | ||
1655 | 120 | WaveformWidgetRenderer(); | ||
1656 | 121 | private: | 124 | private: |
1657 | 122 | DISALLOW_COPY_AND_ASSIGN(WaveformWidgetRenderer); | 125 | DISALLOW_COPY_AND_ASSIGN(WaveformWidgetRenderer); |
1658 | 123 | friend class WaveformWidgetFactory; | 126 | friend class WaveformWidgetFactory; |
1659 | 124 | 127 | ||
1660 | === added file 'mixxx/src/waveform/vsyncthread.cpp' | |||
1661 | --- mixxx/src/waveform/vsyncthread.cpp 1970-01-01 00:00:00 +0000 | |||
1662 | +++ mixxx/src/waveform/vsyncthread.cpp 2013-05-01 22:08:27 +0000 | |||
1663 | @@ -0,0 +1,179 @@ | |||
1664 | 1 | |||
1665 | 2 | #include <QThread> | ||
1666 | 3 | #include <QGLWidget> | ||
1667 | 4 | #include <QGLFormat> | ||
1668 | 5 | #include <QTime> | ||
1669 | 6 | #include <qdebug.h> | ||
1670 | 7 | #include <QTime> | ||
1671 | 8 | |||
1672 | 9 | #include "mathstuff.h" | ||
1673 | 10 | #include "vsyncthread.h" | ||
1674 | 11 | #include "util/performancetimer.h" | ||
1675 | 12 | |||
1676 | 13 | #if defined(__APPLE__) | ||
1677 | 14 | |||
1678 | 15 | #elif defined(__WINDOWS__) | ||
1679 | 16 | |||
1680 | 17 | #else | ||
1681 | 18 | extern const QX11Info *qt_x11Info(const QPaintDevice *pd); | ||
1682 | 19 | #endif | ||
1683 | 20 | |||
1684 | 21 | VSyncThread::VSyncThread(QWidget* parent) | ||
1685 | 22 | : QThread(), | ||
1686 | 23 | m_firstRun(false), | ||
1687 | 24 | m_usSyncTime(33333), | ||
1688 | 25 | m_vSyncMode(ST_TIMER), | ||
1689 | 26 | m_syncOk(false), | ||
1690 | 27 | m_rtErrorCnt(0), | ||
1691 | 28 | m_swapWait(0), | ||
1692 | 29 | m_displayFrameRate(60.0), | ||
1693 | 30 | m_interval(1) { | ||
1694 | 31 | doRendering = true; | ||
1695 | 32 | } | ||
1696 | 33 | |||
1697 | 34 | VSyncThread::~VSyncThread() { | ||
1698 | 35 | doRendering = false; | ||
1699 | 36 | m_sema.release(2); // Two slots | ||
1700 | 37 | wait(); | ||
1701 | 38 | //delete m_glw; | ||
1702 | 39 | } | ||
1703 | 40 | |||
1704 | 41 | void VSyncThread::stop() | ||
1705 | 42 | { | ||
1706 | 43 | doRendering = false; | ||
1707 | 44 | } | ||
1708 | 45 | |||
1709 | 46 | |||
1710 | 47 | void VSyncThread::run() { | ||
1711 | 48 | QThread::currentThread()->setObjectName("VSyncThread"); | ||
1712 | 49 | |||
1713 | 50 | int usRest; | ||
1714 | 51 | int usLast; | ||
1715 | 52 | |||
1716 | 53 | m_usWait = m_usSyncTime; | ||
1717 | 54 | m_timer.start(); | ||
1718 | 55 | |||
1719 | 56 | while (doRendering) { | ||
1720 | 57 | if (m_vSyncMode == ST_FREE) { | ||
1721 | 58 | // for benchmark only! | ||
1722 | 59 | emit(vsync1()); // renders the waveform, Possible delayed due to anti tearing | ||
1723 | 60 | m_sema.acquire(); | ||
1724 | 61 | emit(vsync2()); // swaps the new waveform to front | ||
1725 | 62 | m_sema.acquire(); | ||
1726 | 63 | m_timer.restart(); | ||
1727 | 64 | m_usWait = 1000; | ||
1728 | 65 | usleep(1000); | ||
1729 | 66 | } else { // if (m_vSyncMode == ST_TIMER) { | ||
1730 | 67 | usRest = m_usWait - m_timer.elapsed() / 1000; | ||
1731 | 68 | // waiting for interval by sleep | ||
1732 | 69 | if (usRest > 100) { | ||
1733 | 70 | usleep(usRest); | ||
1734 | 71 | } | ||
1735 | 72 | |||
1736 | 73 | emit(vsync2()); // swaps the new waveform to front in case of gl-wf | ||
1737 | 74 | m_sema.acquire(); // wait until swap was scheduled. It might be delayed due to driver vSync settings | ||
1738 | 75 | // <- Assume we are VSynced here -> | ||
1739 | 76 | usLast = m_timer.restart() / 1000; | ||
1740 | 77 | if (usRest < 0) { | ||
1741 | 78 | // Our swapping call was already delayed | ||
1742 | 79 | // The real swap might happens on the following VSync, depending on driver settings | ||
1743 | 80 | m_rtErrorCnt++; // Count as Real Time Error | ||
1744 | 81 | } | ||
1745 | 82 | // try to stay in right intervals | ||
1746 | 83 | usRest = m_usWait - usLast; | ||
1747 | 84 | m_usWait = m_usSyncTime + (usRest % m_usSyncTime); | ||
1748 | 85 | emit(vsync1()); // renders the new waveform. | ||
1749 | 86 | m_sema.acquire(); // wait until rendreing was scheduled. It might be delayed due a pending swap (depends one driver vSync settings) | ||
1750 | 87 | // qDebug() << "ST_TIMER " << usLast << usRest; | ||
1751 | 88 | } | ||
1752 | 89 | } | ||
1753 | 90 | } | ||
1754 | 91 | |||
1755 | 92 | |||
1756 | 93 | void VSyncThread::postRender(QGLWidget* glw, int index) { | ||
1757 | 94 | // No need for glw->makeCurrent() here. | ||
1758 | 95 | // qDebug() << "postRender" << m_timer.elapsed(); | ||
1759 | 96 | #if defined(__APPLE__) | ||
1760 | 97 | glw->swapBuffers(); | ||
1761 | 98 | #elif defined(__WINDOWS__) | ||
1762 | 99 | glw->swapBuffers(); | ||
1763 | 100 | #else | ||
1764 | 101 | const QX11Info *xinfo = qt_x11Info(glw); | ||
1765 | 102 | glXSwapBuffers(xinfo->display(), glw->winId()); | ||
1766 | 103 | #endif | ||
1767 | 104 | } | ||
1768 | 105 | |||
1769 | 106 | int VSyncThread::elapsed() { | ||
1770 | 107 | return m_timer.elapsed() / 1000; | ||
1771 | 108 | } | ||
1772 | 109 | |||
1773 | 110 | void VSyncThread::setUsSyncTime(int syncTime) { | ||
1774 | 111 | m_usSyncTime = syncTime; | ||
1775 | 112 | double frameRate = 60.0; | ||
1776 | 113 | m_interval = round(m_displayFrameRate * m_usSyncTime / 1000); | ||
1777 | 114 | } | ||
1778 | 115 | |||
1779 | 116 | void VSyncThread::setVSyncType(int type) { | ||
1780 | 117 | if (type >= (int)VSyncThread::ST_COUNT) { | ||
1781 | 118 | type = VSyncThread::ST_TIMER; | ||
1782 | 119 | } | ||
1783 | 120 | m_vSyncMode = (enum VSyncMode)type; | ||
1784 | 121 | m_rtErrorCnt = 0; | ||
1785 | 122 | m_firstRun = true; | ||
1786 | 123 | } | ||
1787 | 124 | |||
1788 | 125 | int VSyncThread::usToNextSync() { | ||
1789 | 126 | int usRest = m_usWait - m_timer.elapsed() / 1000; | ||
1790 | 127 | if (usRest < 0) { | ||
1791 | 128 | usRest %= m_usSyncTime; | ||
1792 | 129 | usRest += m_usSyncTime; | ||
1793 | 130 | } | ||
1794 | 131 | return usRest; | ||
1795 | 132 | } | ||
1796 | 133 | |||
1797 | 134 | int VSyncThread::usFromTimerToNextSync(PerformanceTimer* timer) { | ||
1798 | 135 | int difference = m_timer.difference(timer) / 1000; | ||
1799 | 136 | return difference + m_usWait; | ||
1800 | 137 | } | ||
1801 | 138 | |||
1802 | 139 | int VSyncThread::rtErrorCnt() { | ||
1803 | 140 | return m_rtErrorCnt; | ||
1804 | 141 | } | ||
1805 | 142 | |||
1806 | 143 | void VSyncThread::vsyncSlotFinished() { | ||
1807 | 144 | m_sema.release(); | ||
1808 | 145 | } | ||
1809 | 146 | |||
1810 | 147 | void VSyncThread::getAvailableVSyncTypes(QList<QPair<int, QString > >* pList) { | ||
1811 | 148 | QPair<int, QString > pair; | ||
1812 | 149 | |||
1813 | 150 | for (int i = (int)VSyncThread::ST_TIMER; i < (int)VSyncThread::ST_COUNT; i++) { | ||
1814 | 151 | //if (isAvailable(type)) // TODO | ||
1815 | 152 | { | ||
1816 | 153 | enum VSyncMode mode = (enum VSyncMode)i; | ||
1817 | 154 | |||
1818 | 155 | QString name; | ||
1819 | 156 | switch (mode) { | ||
1820 | 157 | case VSyncThread::ST_TIMER: | ||
1821 | 158 | name = tr("Timer (Fallback)"); | ||
1822 | 159 | break; | ||
1823 | 160 | case VSyncThread::ST_MESA_VBLANK_MODE_1: | ||
1824 | 161 | name = tr("MESA vblank_mode = 1"); | ||
1825 | 162 | break; | ||
1826 | 163 | case VSyncThread::ST_SGI_VIDEO_SYNC: | ||
1827 | 164 | name = tr("Wait for Video sync"); | ||
1828 | 165 | break; | ||
1829 | 166 | case VSyncThread::ST_OML_SYNC_CONTROL: | ||
1830 | 167 | name = tr("Sync Control"); | ||
1831 | 168 | break; | ||
1832 | 169 | case VSyncThread::ST_FREE: | ||
1833 | 170 | name = tr("Free + 1 ms (for benchmark only)"); | ||
1834 | 171 | break; | ||
1835 | 172 | default: | ||
1836 | 173 | break; | ||
1837 | 174 | } | ||
1838 | 175 | QPair<int, QString > pair = QPair<int, QString >(i, name); | ||
1839 | 176 | pList->append(pair); | ||
1840 | 177 | } | ||
1841 | 178 | } | ||
1842 | 179 | } | ||
1843 | 0 | 180 | ||
1844 | === added file 'mixxx/src/waveform/vsyncthread.h' | |||
1845 | --- mixxx/src/waveform/vsyncthread.h 1970-01-01 00:00:00 +0000 | |||
1846 | +++ mixxx/src/waveform/vsyncthread.h 2013-05-01 22:08:27 +0000 | |||
1847 | @@ -0,0 +1,109 @@ | |||
1848 | 1 | #ifndef VSYNCTHREAD_H | ||
1849 | 2 | #define VSYNCTHREAD_H | ||
1850 | 3 | |||
1851 | 4 | #include <QTime> | ||
1852 | 5 | #include <QThread> | ||
1853 | 6 | #include <QSemaphore> | ||
1854 | 7 | #include <QPair> | ||
1855 | 8 | |||
1856 | 9 | #include <qx11info_x11.h> | ||
1857 | 10 | #include "util/performancetimer.h" | ||
1858 | 11 | |||
1859 | 12 | |||
1860 | 13 | #if defined(__APPLE__) | ||
1861 | 14 | |||
1862 | 15 | #elif defined(__WINDOWS__) | ||
1863 | 16 | |||
1864 | 17 | #else | ||
1865 | 18 | #include <GL/glx.h> | ||
1866 | 19 | #include "GL/glxext.h" | ||
1867 | 20 | #endif | ||
1868 | 21 | |||
1869 | 22 | |||
1870 | 23 | class QGLWidget; | ||
1871 | 24 | |||
1872 | 25 | class VSyncThread : public QThread { | ||
1873 | 26 | Q_OBJECT | ||
1874 | 27 | public: | ||
1875 | 28 | enum VSyncMode { | ||
1876 | 29 | ST_TIMER = 0, | ||
1877 | 30 | ST_MESA_VBLANK_MODE_1, | ||
1878 | 31 | ST_SGI_VIDEO_SYNC, | ||
1879 | 32 | ST_OML_SYNC_CONTROL, | ||
1880 | 33 | ST_FREE, | ||
1881 | 34 | ST_COUNT // Dummy Type at last, counting possible types | ||
1882 | 35 | }; | ||
1883 | 36 | |||
1884 | 37 | VSyncThread(QWidget* parent); | ||
1885 | 38 | ~VSyncThread(); | ||
1886 | 39 | void run(); | ||
1887 | 40 | void stop(); | ||
1888 | 41 | |||
1889 | 42 | bool waitForVideoSync(QGLWidget* glw); | ||
1890 | 43 | int elapsed(); | ||
1891 | 44 | int usToNextSync(); | ||
1892 | 45 | void setUsSyncTime(int usSyncTimer); | ||
1893 | 46 | void setVSyncType(int mode); | ||
1894 | 47 | int rtErrorCnt(); | ||
1895 | 48 | void setSwapWait(int sw); | ||
1896 | 49 | int usFromTimerToNextSync(PerformanceTimer* timer); | ||
1897 | 50 | void vsyncSlotFinished(); | ||
1898 | 51 | void getAvailableVSyncTypes(QList<QPair<int, QString > >* list); | ||
1899 | 52 | void setupSync(QGLWidget* glw, int index); | ||
1900 | 53 | void postRender(QGLWidget* glw, int index); | ||
1901 | 54 | void waitUntilSwap(QGLWidget* glw); | ||
1902 | 55 | |||
1903 | 56 | signals: | ||
1904 | 57 | void vsync1(); | ||
1905 | 58 | void vsync2(); | ||
1906 | 59 | |||
1907 | 60 | private: | ||
1908 | 61 | bool doRendering; | ||
1909 | 62 | QGLWidget *m_glw; | ||
1910 | 63 | |||
1911 | 64 | #if defined(__APPLE__) | ||
1912 | 65 | |||
1913 | 66 | #elif defined(__WINDOWS__) | ||
1914 | 67 | |||
1915 | 68 | #else | ||
1916 | 69 | void initGlxext(QGLWidget* glw); | ||
1917 | 70 | bool glXExtensionSupported(Display *dpy, int screen, const char *extension); | ||
1918 | 71 | |||
1919 | 72 | PFNGLXGETVIDEOSYNCSGIPROC glXGetVideoSyncSGI; | ||
1920 | 73 | PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI; | ||
1921 | 74 | |||
1922 | 75 | PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; | ||
1923 | 76 | |||
1924 | 77 | PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; | ||
1925 | 78 | |||
1926 | 79 | PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML; | ||
1927 | 80 | PFNGLXGETMSCRATEOMLPROC glXGetMscRateOML; | ||
1928 | 81 | PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML; | ||
1929 | 82 | PFNGLXWAITFORMSCOMLPROC glXWaitForMscOML; | ||
1930 | 83 | PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML; | ||
1931 | 84 | |||
1932 | 85 | PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA; | ||
1933 | 86 | |||
1934 | 87 | uint m_counter; | ||
1935 | 88 | |||
1936 | 89 | int64_t m_target_msc; | ||
1937 | 90 | Display* m_dpy; | ||
1938 | 91 | GLXDrawable m_drawable; | ||
1939 | 92 | |||
1940 | 93 | #endif | ||
1941 | 94 | |||
1942 | 95 | bool m_firstRun; | ||
1943 | 96 | int m_usSyncTime; | ||
1944 | 97 | int m_usWait; | ||
1945 | 98 | enum VSyncMode m_vSyncMode; | ||
1946 | 99 | bool m_syncOk; | ||
1947 | 100 | int m_rtErrorCnt; | ||
1948 | 101 | int m_swapWait; | ||
1949 | 102 | PerformanceTimer m_timer; | ||
1950 | 103 | QSemaphore m_sema; | ||
1951 | 104 | double m_displayFrameRate; | ||
1952 | 105 | int m_interval; | ||
1953 | 106 | }; | ||
1954 | 107 | |||
1955 | 108 | |||
1956 | 109 | #endif // VSYNCTHREAD_H | ||
1957 | 0 | 110 | ||
1958 | === modified file 'mixxx/src/waveform/waveformwidgetfactory.cpp' | |||
1959 | --- mixxx/src/waveform/waveformwidgetfactory.cpp 2012-12-13 22:46:16 +0000 | |||
1960 | +++ mixxx/src/waveform/waveformwidgetfactory.cpp 2013-05-01 22:08:27 +0000 | |||
1961 | @@ -18,8 +18,13 @@ | |||
1962 | 18 | #include "waveform/widgets/qtwaveformwidget.h" | 18 | #include "waveform/widgets/qtwaveformwidget.h" |
1963 | 19 | #include "waveform/widgets/qtsimplewaveformwidget.h" | 19 | #include "waveform/widgets/qtsimplewaveformwidget.h" |
1964 | 20 | #include "waveform/widgets/glslwaveformwidget.h" | 20 | #include "waveform/widgets/glslwaveformwidget.h" |
1965 | 21 | #include "waveform/widgets/glvsynctestwidget.h" | ||
1966 | 21 | #include "waveform/widgets/waveformwidgetabstract.h" | 22 | #include "waveform/widgets/waveformwidgetabstract.h" |
1967 | 22 | #include "widget/wwaveformviewer.h" | 23 | #include "widget/wwaveformviewer.h" |
1968 | 24 | #include "waveform/vsyncthread.h" | ||
1969 | 25 | #include "util/cmdlineargs.h" | ||
1970 | 26 | |||
1971 | 27 | #include "util/performancetimer.h" | ||
1972 | 23 | #include "util/timer.h" | 28 | #include "util/timer.h" |
1973 | 24 | 29 | ||
1974 | 25 | /////////////////////////////////////////// | 30 | /////////////////////////////////////////// |
1975 | @@ -31,6 +36,12 @@ | |||
1976 | 31 | 36 | ||
1977 | 32 | /////////////////////////////////////////// | 37 | /////////////////////////////////////////// |
1978 | 33 | 38 | ||
1979 | 39 | WaveformWidgetHolder::WaveformWidgetHolder() | ||
1980 | 40 | : m_waveformWidget(NULL), | ||
1981 | 41 | m_waveformViewer(NULL), | ||
1982 | 42 | m_visualNodeCache(QDomNode()) { | ||
1983 | 43 | } | ||
1984 | 44 | |||
1985 | 34 | WaveformWidgetHolder::WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget, | 45 | WaveformWidgetHolder::WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget, |
1986 | 35 | WWaveformViewer* waveformViewer, | 46 | WWaveformViewer* waveformViewer, |
1987 | 36 | const QDomNode& visualNodeCache) | 47 | const QDomNode& visualNodeCache) |
1988 | @@ -51,8 +62,8 @@ | |||
1989 | 51 | m_overviewNormalized(false), | 62 | m_overviewNormalized(false), |
1990 | 52 | m_openGLAvailable(false), | 63 | m_openGLAvailable(false), |
1991 | 53 | m_openGLShaderAvailable(false), | 64 | m_openGLShaderAvailable(false), |
1994 | 54 | m_time(new QTime()), | 65 | m_vsyncThread(NULL), |
1995 | 55 | m_lastFrameTime(0), | 66 | m_frameCnt(0), |
1996 | 56 | m_actualFrameRate(0) { | 67 | m_actualFrameRate(0) { |
1997 | 57 | 68 | ||
1998 | 58 | m_visualGain[All] = 1.5; | 69 | m_visualGain[All] = 1.5; |
1999 | @@ -129,17 +140,20 @@ | |||
2000 | 129 | } | 140 | } |
2001 | 130 | 141 | ||
2002 | 131 | evaluateWidgets(); | 142 | evaluateWidgets(); |
2004 | 132 | start(); | 143 | m_time.start(); |
2005 | 133 | } | 144 | } |
2006 | 134 | 145 | ||
2007 | 135 | WaveformWidgetFactory::~WaveformWidgetFactory() { | 146 | WaveformWidgetFactory::~WaveformWidgetFactory() { |
2009 | 136 | delete m_time; | 147 | if (m_vsyncThread) { |
2010 | 148 | delete m_vsyncThread; | ||
2011 | 149 | } | ||
2012 | 137 | } | 150 | } |
2013 | 138 | 151 | ||
2015 | 139 | bool WaveformWidgetFactory::setConfig(ConfigObject<ConfigValue> *config){ | 152 | bool WaveformWidgetFactory::setConfig(ConfigObject<ConfigValue> *config) { |
2016 | 140 | m_config = config; | 153 | m_config = config; |
2018 | 141 | if (!m_config) | 154 | if (!m_config) { |
2019 | 142 | return false; | 155 | return false; |
2020 | 156 | } | ||
2021 | 143 | 157 | ||
2022 | 144 | bool ok = false; | 158 | bool ok = false; |
2023 | 145 | 159 | ||
2024 | @@ -150,6 +164,9 @@ | |||
2025 | 150 | m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate)); | 164 | m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate)); |
2026 | 151 | } | 165 | } |
2027 | 152 | 166 | ||
2028 | 167 | int vsync = m_config->getValueString(ConfigKey("[Waveform]","VSync"),"0").toInt(); | ||
2029 | 168 | setVSyncType(vsync); | ||
2030 | 169 | |||
2031 | 153 | int defaultZoom = m_config->getValueString(ConfigKey("[Waveform]","DefaultZoom")).toInt(&ok); | 170 | int defaultZoom = m_config->getValueString(ConfigKey("[Waveform]","DefaultZoom")).toInt(&ok); |
2032 | 154 | if (ok) { | 171 | if (ok) { |
2033 | 155 | setDefaultZoom(defaultZoom); | 172 | setDefaultZoom(defaultZoom); |
2034 | @@ -192,25 +209,8 @@ | |||
2035 | 192 | return true; | 209 | return true; |
2036 | 193 | } | 210 | } |
2037 | 194 | 211 | ||
2038 | 195 | void WaveformWidgetFactory::start() { | ||
2039 | 196 | //qDebug() << "WaveformWidgetFactory::start"; | ||
2040 | 197 | killTimer(m_mainTimerId); | ||
2041 | 198 | m_mainTimerId = startTimer(1000.0/double(m_frameRate)); | ||
2042 | 199 | } | ||
2043 | 200 | |||
2044 | 201 | void WaveformWidgetFactory::stop() { | ||
2045 | 202 | killTimer(m_mainTimerId); | ||
2046 | 203 | m_mainTimerId = -1; | ||
2047 | 204 | } | ||
2048 | 205 | |||
2049 | 206 | void WaveformWidgetFactory::timerEvent(QTimerEvent *timerEvent) { | ||
2050 | 207 | if (timerEvent->timerId() == m_mainTimerId) { | ||
2051 | 208 | refresh(); | ||
2052 | 209 | } | ||
2053 | 210 | } | ||
2054 | 211 | |||
2055 | 212 | void WaveformWidgetFactory::destroyWidgets() { | 212 | void WaveformWidgetFactory::destroyWidgets() { |
2057 | 213 | for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) { | 213 | for (int i = 0; i < m_waveformWidgetHolders.size(); i++) { |
2058 | 214 | WaveformWidgetAbstract* pWidget = m_waveformWidgetHolders[i].m_waveformWidget;; | 214 | WaveformWidgetAbstract* pWidget = m_waveformWidgetHolders[i].m_waveformWidget;; |
2059 | 215 | m_waveformWidgetHolders[i].m_waveformWidget = NULL; | 215 | m_waveformWidgetHolders[i].m_waveformWidget = NULL; |
2060 | 216 | delete pWidget; | 216 | delete pWidget; |
2061 | @@ -247,6 +247,7 @@ | |||
2062 | 247 | } | 247 | } |
2063 | 248 | 248 | ||
2064 | 249 | viewer->setZoom(m_defaultZoom); | 249 | viewer->setZoom(m_defaultZoom); |
2065 | 250 | viewer->update(); | ||
2066 | 250 | 251 | ||
2067 | 251 | qDebug() << "WaveformWidgetFactory::setWaveformWidget - waveform widget added in factory, index" << index; | 252 | qDebug() << "WaveformWidgetFactory::setWaveformWidget - waveform widget added in factory, index" << index; |
2068 | 252 | 253 | ||
2069 | @@ -254,11 +255,25 @@ | |||
2070 | 254 | } | 255 | } |
2071 | 255 | 256 | ||
2072 | 256 | void WaveformWidgetFactory::setFrameRate(int frameRate) { | 257 | void WaveformWidgetFactory::setFrameRate(int frameRate) { |
2074 | 257 | m_frameRate = math_min(60, math_max(10, frameRate)); | 258 | m_frameRate = math_min(120, math_max(1, frameRate)); |
2075 | 258 | if (m_config) { | 259 | if (m_config) { |
2076 | 259 | m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate)); | 260 | m_config->set(ConfigKey("[Waveform]","FrameRate"), ConfigValue(m_frameRate)); |
2077 | 260 | } | 261 | } |
2079 | 261 | start(); | 262 | m_vsyncThread->setUsSyncTime(1000000/m_frameRate); |
2080 | 263 | } | ||
2081 | 264 | |||
2082 | 265 | |||
2083 | 266 | void WaveformWidgetFactory::setVSyncType(int type) { | ||
2084 | 267 | if (m_config) { | ||
2085 | 268 | m_config->set(ConfigKey("[Waveform]","VSync"), ConfigValue((int)type)); | ||
2086 | 269 | } | ||
2087 | 270 | |||
2088 | 271 | m_vSyncType = type; | ||
2089 | 272 | m_vsyncThread->setVSyncType(type); | ||
2090 | 273 | } | ||
2091 | 274 | |||
2092 | 275 | int WaveformWidgetFactory::getVSyncType() { | ||
2093 | 276 | return m_vSyncType; | ||
2094 | 262 | } | 277 | } |
2095 | 263 | 278 | ||
2096 | 264 | bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type) { | 279 | bool WaveformWidgetFactory::setWidgetType(WaveformWidgetType::Type type) { |
2097 | @@ -266,7 +281,7 @@ | |||
2098 | 266 | return true; | 281 | return true; |
2099 | 267 | 282 | ||
2100 | 268 | // check if type is acceptable | 283 | // check if type is acceptable |
2102 | 269 | for (unsigned int i = 0; i < m_waveformWidgetHandles.size(); i++) { | 284 | for (int i = 0; i < m_waveformWidgetHandles.size(); i++) { |
2103 | 270 | WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i]; | 285 | WaveformWidgetAbstractHandle& handle = m_waveformWidgetHandles[i]; |
2104 | 271 | if (handle.m_type == type) { | 286 | if (handle.m_type == type) { |
2105 | 272 | // type is acceptable | 287 | // type is acceptable |
2106 | @@ -307,7 +322,7 @@ | |||
2107 | 307 | //qDebug() << "recreate start"; | 322 | //qDebug() << "recreate start"; |
2108 | 308 | 323 | ||
2109 | 309 | //re-create/setup all waveform widgets | 324 | //re-create/setup all waveform widgets |
2111 | 310 | for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) { | 325 | for (int i = 0; i < m_waveformWidgetHolders.size(); i++) { |
2112 | 311 | WaveformWidgetHolder& holder = m_waveformWidgetHolders[i]; | 326 | WaveformWidgetHolder& holder = m_waveformWidgetHolders[i]; |
2113 | 312 | WaveformWidgetAbstract* previousWidget = holder.m_waveformWidget; | 327 | WaveformWidgetAbstract* previousWidget = holder.m_waveformWidget; |
2114 | 313 | TrackPointer pTrack = previousWidget->getTrackInfo(); | 328 | TrackPointer pTrack = previousWidget->getTrackInfo(); |
2115 | @@ -325,6 +340,8 @@ | |||
2116 | 325 | //viewer->resize(viewer->size()); | 340 | //viewer->resize(viewer->size()); |
2117 | 326 | widget->resize(viewer->width(), viewer->height()); | 341 | widget->resize(viewer->width(), viewer->height()); |
2118 | 327 | widget->setTrack(pTrack); | 342 | widget->setTrack(pTrack); |
2119 | 343 | widget->getWidget()->show(); | ||
2120 | 344 | viewer->update(); | ||
2121 | 328 | } | 345 | } |
2122 | 329 | 346 | ||
2123 | 330 | m_skipRender = false; | 347 | m_skipRender = false; |
2124 | @@ -339,7 +356,7 @@ | |||
2125 | 339 | m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom)); | 356 | m_config->set(ConfigKey("[Waveform]","DefaultZoom"), ConfigValue(m_defaultZoom)); |
2126 | 340 | } | 357 | } |
2127 | 341 | 358 | ||
2129 | 342 | for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) { | 359 | for (int i = 0; i < m_waveformWidgetHolders.size(); i++) { |
2130 | 343 | m_waveformWidgetHolders[i].m_waveformViewer->setZoom(m_defaultZoom); | 360 | m_waveformWidgetHolders[i].m_waveformViewer->setZoom(m_defaultZoom); |
2131 | 344 | } | 361 | } |
2132 | 345 | } | 362 | } |
2133 | @@ -355,7 +372,7 @@ | |||
2134 | 355 | } | 372 | } |
2135 | 356 | 373 | ||
2136 | 357 | int refZoom = m_waveformWidgetHolders[0].m_waveformWidget->getZoomFactor(); | 374 | int refZoom = m_waveformWidgetHolders[0].m_waveformWidget->getZoomFactor(); |
2138 | 358 | for (unsigned int i = 1; i < m_waveformWidgetHolders.size(); i++) { | 375 | for (int i = 1; i < m_waveformWidgetHolders.size(); i++) { |
2139 | 359 | m_waveformWidgetHolders[i].m_waveformViewer->setZoom(refZoom); | 376 | m_waveformWidgetHolders[i].m_waveformViewer->setZoom(refZoom); |
2140 | 360 | } | 377 | } |
2141 | 361 | } | 378 | } |
2142 | @@ -390,29 +407,67 @@ | |||
2143 | 390 | } | 407 | } |
2144 | 391 | 408 | ||
2145 | 392 | void WaveformWidgetFactory::refresh() { | 409 | void WaveformWidgetFactory::refresh() { |
2146 | 393 | if (m_skipRender) | ||
2147 | 394 | return; | ||
2148 | 395 | |||
2149 | 396 | ScopedTimer t(QString("WaveformWidgetFactory::refresh() %1waveforms") | 410 | ScopedTimer t(QString("WaveformWidgetFactory::refresh() %1waveforms") |
2169 | 397 | .arg(m_waveformWidgetHolders.size())); | 411 | .arg(m_waveformWidgetHolders.size())); |
2170 | 398 | 412 | ||
2171 | 399 | for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) | 413 | int paintersSetupTime0 = 0; |
2172 | 400 | m_waveformWidgetHolders[i].m_waveformWidget->preRender(); | 414 | int paintersSetupTime1 = 0; |
2173 | 401 | 415 | ||
2174 | 402 | for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) | 416 | if (!m_skipRender) { |
2175 | 403 | m_waveformWidgetHolders[i].m_waveformWidget->render(); | 417 | if (m_type) { // no regular updates for an empty waveform |
2176 | 404 | 418 | // next rendered frame is displayed after next buffer swap and than after VSync | |
2177 | 405 | for (unsigned int i = 0; i < m_waveformWidgetHolders.size(); i++) | 419 | for (int i = 0; i < m_waveformWidgetHolders.size(); i++) { |
2178 | 406 | m_waveformWidgetHolders[i].m_waveformWidget->postRender(); | 420 | // Calculate play position for the new Frame in following run |
2179 | 407 | 421 | m_waveformWidgetHolders[i].m_waveformWidget->preRender(m_vsyncThread); | |
2180 | 408 | // Notify all other waveform-like widgets (e.g. WSpinny's) that they should | 422 | } |
2181 | 409 | // update. | 423 | //qDebug() << "prerender" << m_vsyncThread->elapsed(); |
2182 | 410 | emit(waveformUpdateTick()); | 424 | |
2183 | 411 | 425 | // It may happen that there is an artificially delayed due to | |
2184 | 412 | m_lastFrameTime = m_time->restart(); | 426 | // anti tearing driver settings |
2185 | 413 | if (m_lastFrameTime && m_lastFrameTime <= 1000) { | 427 | // all render commands are delayed until the swap from the previous run is executed |
2186 | 414 | m_actualFrameRate = 1000.0/(double)(m_lastFrameTime); | 428 | for (int i = 0; i < m_waveformWidgetHolders.size(); i++) { |
2187 | 415 | } | 429 | (void)m_waveformWidgetHolders[i].m_waveformWidget->render(); |
2188 | 430 | // qDebug() << "render" << i << m_vsyncThread->elapsed(); | ||
2189 | 431 | } | ||
2190 | 432 | } | ||
2191 | 433 | |||
2192 | 434 | // Notify all other waveform-like widgets (e.g. WSpinny's) that they should | ||
2193 | 435 | // update. | ||
2194 | 436 | //int t1 = m_vsyncThread->elapsed(); | ||
2195 | 437 | emit(waveformUpdateTick()); | ||
2196 | 438 | //qDebug() << "emit" << m_vsyncThread->elapsed() - t1; | ||
2197 | 439 | |||
2198 | 440 | m_frameCnt += 1.0; | ||
2199 | 441 | int timeCnt = m_time.elapsed(); | ||
2200 | 442 | if (timeCnt > 1000) { | ||
2201 | 443 | m_time.start(); | ||
2202 | 444 | m_frameCnt = m_frameCnt * 1000 / timeCnt; // latency correction | ||
2203 | 445 | emit(waveformMeasured(m_frameCnt, m_vsyncThread->rtErrorCnt())); | ||
2204 | 446 | m_frameCnt = 0.0; | ||
2205 | 447 | } | ||
2206 | 448 | } | ||
2207 | 449 | //qDebug() << "refresh end" << m_vsyncThread->elapsed(); | ||
2208 | 450 | m_vsyncThread->vsyncSlotFinished(); | ||
2209 | 451 | } | ||
2210 | 452 | |||
2211 | 453 | void WaveformWidgetFactory::postRefresh() { | ||
2212 | 454 | // Do this in an extra slot to be sure to hit the desired interval | ||
2213 | 455 | if (!m_skipRender) { | ||
2214 | 456 | if (m_type) { // no regular updates for an empty waveform | ||
2215 | 457 | // Show rendered buffer from last refresh() run | ||
2216 | 458 | //qDebug() << "postRefresh start" << m_vsyncThread->elapsed(); | ||
2217 | 459 | for (int i = 0; i < m_waveformWidgetHolders.size(); i++) { | ||
2218 | 460 | QGLWidget* glw = dynamic_cast<QGLWidget*>( | ||
2219 | 461 | m_waveformWidgetHolders[i].m_waveformWidget->getWidget()); | ||
2220 | 462 | if (glw) { | ||
2221 | 463 | m_vsyncThread->postRender(glw, i); | ||
2222 | 464 | } | ||
2223 | 465 | //qDebug() << "postRefresh x" << m_vsyncThread->elapsed(); | ||
2224 | 466 | } | ||
2225 | 467 | } | ||
2226 | 468 | } | ||
2227 | 469 | //qDebug() << "postRefresh end" << m_vsyncThread->elapsed(); | ||
2228 | 470 | m_vsyncThread->vsyncSlotFinished(); | ||
2229 | 416 | } | 471 | } |
2230 | 417 | 472 | ||
2231 | 418 | WaveformWidgetType::Type WaveformWidgetFactory::autoChooseWidgetType() const { | 473 | WaveformWidgetType::Type WaveformWidgetFactory::autoChooseWidgetType() const { |
2232 | @@ -435,12 +490,14 @@ | |||
2233 | 435 | QString widgetName; | 490 | QString widgetName; |
2234 | 436 | bool useOpenGl; | 491 | bool useOpenGl; |
2235 | 437 | bool useOpenGLShaders; | 492 | bool useOpenGLShaders; |
2236 | 493 | bool developerOnly; | ||
2237 | 438 | 494 | ||
2238 | 439 | switch(type) { | 495 | switch(type) { |
2239 | 440 | case WaveformWidgetType::EmptyWaveform: | 496 | case WaveformWidgetType::EmptyWaveform: |
2240 | 441 | widgetName = EmptyWaveformWidget::getWaveformWidgetName(); | 497 | widgetName = EmptyWaveformWidget::getWaveformWidgetName(); |
2241 | 442 | useOpenGl = EmptyWaveformWidget::useOpenGl(); | 498 | useOpenGl = EmptyWaveformWidget::useOpenGl(); |
2242 | 443 | useOpenGLShaders = EmptyWaveformWidget::useOpenGLShaders(); | 499 | useOpenGLShaders = EmptyWaveformWidget::useOpenGLShaders(); |
2243 | 500 | developerOnly = EmptyWaveformWidget::developerOnly(); | ||
2244 | 444 | break; | 501 | break; |
2245 | 445 | case WaveformWidgetType::SoftwareSimpleWaveform: | 502 | case WaveformWidgetType::SoftwareSimpleWaveform: |
2246 | 446 | continue; // //TODO(vrince): | 503 | continue; // //TODO(vrince): |
2247 | @@ -448,37 +505,52 @@ | |||
2248 | 448 | widgetName = SoftwareWaveformWidget::getWaveformWidgetName(); | 505 | widgetName = SoftwareWaveformWidget::getWaveformWidgetName(); |
2249 | 449 | useOpenGl = SoftwareWaveformWidget::useOpenGl(); | 506 | useOpenGl = SoftwareWaveformWidget::useOpenGl(); |
2250 | 450 | useOpenGLShaders = SoftwareWaveformWidget::useOpenGLShaders(); | 507 | useOpenGLShaders = SoftwareWaveformWidget::useOpenGLShaders(); |
2251 | 508 | developerOnly = SoftwareWaveformWidget::developerOnly(); | ||
2252 | 451 | break; | 509 | break; |
2253 | 452 | case WaveformWidgetType::HSVWaveform: | 510 | case WaveformWidgetType::HSVWaveform: |
2254 | 453 | widgetName = HSVWaveformWidget::getWaveformWidgetName(); | 511 | widgetName = HSVWaveformWidget::getWaveformWidgetName(); |
2255 | 454 | useOpenGl = HSVWaveformWidget::useOpenGl(); | 512 | useOpenGl = HSVWaveformWidget::useOpenGl(); |
2256 | 455 | useOpenGLShaders = HSVWaveformWidget::useOpenGLShaders(); | 513 | useOpenGLShaders = HSVWaveformWidget::useOpenGLShaders(); |
2257 | 514 | developerOnly = HSVWaveformWidget::developerOnly(); | ||
2258 | 456 | break; | 515 | break; |
2259 | 457 | case WaveformWidgetType::QtSimpleWaveform: | 516 | case WaveformWidgetType::QtSimpleWaveform: |
2260 | 458 | widgetName = QtSimpleWaveformWidget::getWaveformWidgetName(); | 517 | widgetName = QtSimpleWaveformWidget::getWaveformWidgetName(); |
2261 | 459 | useOpenGl = QtSimpleWaveformWidget::useOpenGl(); | 518 | useOpenGl = QtSimpleWaveformWidget::useOpenGl(); |
2262 | 460 | useOpenGLShaders = QtSimpleWaveformWidget::useOpenGLShaders(); | 519 | useOpenGLShaders = QtSimpleWaveformWidget::useOpenGLShaders(); |
2263 | 520 | developerOnly = QtSimpleWaveformWidget::developerOnly(); | ||
2264 | 461 | break; | 521 | break; |
2265 | 462 | case WaveformWidgetType::QtWaveform: | 522 | case WaveformWidgetType::QtWaveform: |
2266 | 463 | widgetName = QtWaveformWidget::getWaveformWidgetName(); | 523 | widgetName = QtWaveformWidget::getWaveformWidgetName(); |
2267 | 464 | useOpenGl = QtWaveformWidget::useOpenGl(); | 524 | useOpenGl = QtWaveformWidget::useOpenGl(); |
2268 | 465 | useOpenGLShaders = QtWaveformWidget::useOpenGLShaders(); | 525 | useOpenGLShaders = QtWaveformWidget::useOpenGLShaders(); |
2269 | 526 | developerOnly = QtWaveformWidget::developerOnly(); | ||
2270 | 466 | break; | 527 | break; |
2271 | 467 | case WaveformWidgetType::GLSimpleWaveform: | 528 | case WaveformWidgetType::GLSimpleWaveform: |
2272 | 468 | widgetName = GLSimpleWaveformWidget::getWaveformWidgetName(); | 529 | widgetName = GLSimpleWaveformWidget::getWaveformWidgetName(); |
2273 | 469 | useOpenGl = GLSimpleWaveformWidget::useOpenGl(); | 530 | useOpenGl = GLSimpleWaveformWidget::useOpenGl(); |
2274 | 470 | useOpenGLShaders = GLSimpleWaveformWidget::useOpenGLShaders(); | 531 | useOpenGLShaders = GLSimpleWaveformWidget::useOpenGLShaders(); |
2275 | 532 | developerOnly = GLSimpleWaveformWidget::developerOnly(); | ||
2276 | 471 | break; | 533 | break; |
2277 | 472 | case WaveformWidgetType::GLWaveform: | 534 | case WaveformWidgetType::GLWaveform: |
2278 | 473 | widgetName = GLWaveformWidget::getWaveformWidgetName(); | 535 | widgetName = GLWaveformWidget::getWaveformWidgetName(); |
2279 | 474 | useOpenGl = GLWaveformWidget::useOpenGl(); | 536 | useOpenGl = GLWaveformWidget::useOpenGl(); |
2280 | 475 | useOpenGLShaders = GLWaveformWidget::useOpenGLShaders(); | 537 | useOpenGLShaders = GLWaveformWidget::useOpenGLShaders(); |
2281 | 538 | developerOnly = GLWaveformWidget::developerOnly(); | ||
2282 | 476 | break; | 539 | break; |
2283 | 477 | case WaveformWidgetType::GLSLWaveform: | 540 | case WaveformWidgetType::GLSLWaveform: |
2284 | 478 | widgetName = GLSLWaveformWidget::getWaveformWidgetName(); | 541 | widgetName = GLSLWaveformWidget::getWaveformWidgetName(); |
2285 | 479 | useOpenGl = GLSLWaveformWidget::useOpenGl(); | 542 | useOpenGl = GLSLWaveformWidget::useOpenGl(); |
2286 | 480 | useOpenGLShaders = GLSLWaveformWidget::useOpenGLShaders(); | 543 | useOpenGLShaders = GLSLWaveformWidget::useOpenGLShaders(); |
2288 | 481 | break; | 544 | developerOnly = GLSLWaveformWidget::developerOnly(); |
2289 | 545 | break; | ||
2290 | 546 | case WaveformWidgetType::GLVSyncTest: | ||
2291 | 547 | widgetName = GLVSyncTestWidget::getWaveformWidgetName(); | ||
2292 | 548 | useOpenGl = GLVSyncTestWidget::useOpenGl(); | ||
2293 | 549 | useOpenGLShaders = GLVSyncTestWidget::useOpenGLShaders(); | ||
2294 | 550 | developerOnly = GLVSyncTestWidget::developerOnly(); | ||
2295 | 551 | break; | ||
2296 | 552 | default: | ||
2297 | 553 | continue; | ||
2298 | 482 | } | 554 | } |
2299 | 483 | 555 | ||
2300 | 484 | if (useOpenGLShaders) { | 556 | if (useOpenGLShaders) { |
2301 | @@ -499,6 +571,12 @@ | |||
2302 | 499 | handle.m_active = false; | 571 | handle.m_active = false; |
2303 | 500 | continue; | 572 | continue; |
2304 | 501 | } | 573 | } |
2305 | 574 | |||
2306 | 575 | if (developerOnly && !CmdlineArgs::Instance().getDeveloper()) { | ||
2307 | 576 | handle.m_active = false; | ||
2308 | 577 | continue; | ||
2309 | 578 | } | ||
2310 | 579 | |||
2311 | 502 | m_waveformWidgetHandles.push_back(handle); | 580 | m_waveformWidgetHandles.push_back(handle); |
2312 | 503 | } | 581 | } |
2313 | 504 | } | 582 | } |
2314 | @@ -529,6 +607,9 @@ | |||
2315 | 529 | case WaveformWidgetType::GLSLWaveform: | 607 | case WaveformWidgetType::GLSLWaveform: |
2316 | 530 | widget = new GLSLWaveformWidget(viewer->getGroup(), viewer); | 608 | widget = new GLSLWaveformWidget(viewer->getGroup(), viewer); |
2317 | 531 | break; | 609 | break; |
2318 | 610 | case WaveformWidgetType::GLVSyncTest: | ||
2319 | 611 | widget = new GLVSyncTestWidget(viewer->getGroup(), viewer); | ||
2320 | 612 | break; | ||
2321 | 532 | default: | 613 | default: |
2322 | 533 | //case WaveformWidgetType::SoftwareSimpleWaveform: TODO: (vrince) | 614 | //case WaveformWidgetType::SoftwareSimpleWaveform: TODO: (vrince) |
2323 | 534 | //case WaveformWidgetType::EmptyWaveform: | 615 | //case WaveformWidgetType::EmptyWaveform: |
2324 | @@ -552,8 +633,32 @@ | |||
2325 | 552 | } | 633 | } |
2326 | 553 | 634 | ||
2327 | 554 | int WaveformWidgetFactory::findIndexOf(WWaveformViewer* viewer) const { | 635 | int WaveformWidgetFactory::findIndexOf(WWaveformViewer* viewer) const { |
2330 | 555 | for (int i = 0; i < (int)m_waveformWidgetHolders.size(); i++) | 636 | for (int i = 0; i < (int)m_waveformWidgetHolders.size(); i++) { |
2331 | 556 | if (m_waveformWidgetHolders[i].m_waveformViewer == viewer) | 637 | if (m_waveformWidgetHolders[i].m_waveformViewer == viewer) { |
2332 | 557 | return i; | 638 | return i; |
2333 | 639 | } | ||
2334 | 640 | } | ||
2335 | 558 | return -1; | 641 | return -1; |
2336 | 559 | } | 642 | } |
2337 | 643 | |||
2338 | 644 | void WaveformWidgetFactory::startVSync(QWidget *parent) { | ||
2339 | 645 | if (m_vsyncThread) { | ||
2340 | 646 | disconnect(m_vsyncThread, SIGNAL(vsync1()), this, SLOT(refresh())); | ||
2341 | 647 | disconnect(m_vsyncThread, SIGNAL(vsync2()), this, SLOT(postRefresh())); | ||
2342 | 648 | delete m_vsyncThread; | ||
2343 | 649 | } | ||
2344 | 650 | m_vsyncThread = new VSyncThread(parent); | ||
2345 | 651 | m_vsyncThread->start(); | ||
2346 | 652 | |||
2347 | 653 | connect(m_vsyncThread, SIGNAL(vsync1()), | ||
2348 | 654 | this, SLOT(refresh())); | ||
2349 | 655 | connect(m_vsyncThread, SIGNAL(vsync2()), | ||
2350 | 656 | this, SLOT(postRefresh())); | ||
2351 | 657 | |||
2352 | 658 | } | ||
2353 | 659 | |||
2354 | 660 | void WaveformWidgetFactory::getAvailableVSyncTypes(QList<QPair<int, QString > >* pList) { | ||
2355 | 661 | m_vsyncThread->getAvailableVSyncTypes(pList); | ||
2356 | 662 | } | ||
2357 | 663 | |||
2358 | 664 | |||
2359 | 560 | 665 | ||
2360 | === modified file 'mixxx/src/waveform/waveformwidgetfactory.h' | |||
2361 | --- mixxx/src/waveform/waveformwidgetfactory.h 2012-05-30 18:26:44 +0000 | |||
2362 | +++ mixxx/src/waveform/waveformwidgetfactory.h 2013-05-01 22:08:27 +0000 | |||
2363 | @@ -8,14 +8,15 @@ | |||
2364 | 8 | #include "waveform/waveform.h" | 8 | #include "waveform/waveform.h" |
2365 | 9 | 9 | ||
2366 | 10 | #include <QObject> | 10 | #include <QObject> |
2369 | 11 | 11 | #include <QTime> | |
2370 | 12 | #include <vector> | 12 | #include <QVector> |
2371 | 13 | 13 | ||
2372 | 14 | class WWaveformViewer; | 14 | class WWaveformViewer; |
2373 | 15 | class WaveformWidgetAbstract; | 15 | class WaveformWidgetAbstract; |
2374 | 16 | class ControlObjectThreadMain; | 16 | class ControlObjectThreadMain; |
2375 | 17 | class QTimer; | 17 | class QTimer; |
2377 | 18 | class QTime; | 18 | class VSyncThread; |
2378 | 19 | |||
2379 | 19 | 20 | ||
2380 | 20 | class WaveformWidgetAbstractHandle { | 21 | class WaveformWidgetAbstractHandle { |
2381 | 21 | public: | 22 | public: |
2382 | @@ -34,7 +35,9 @@ | |||
2383 | 34 | }; | 35 | }; |
2384 | 35 | 36 | ||
2385 | 36 | class WaveformWidgetHolder { | 37 | class WaveformWidgetHolder { |
2387 | 37 | private: | 38 | public: |
2388 | 39 | WaveformWidgetHolder(); | ||
2389 | 40 | private: | ||
2390 | 38 | WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget, | 41 | WaveformWidgetHolder(WaveformWidgetAbstract* waveformWidget, |
2391 | 39 | WWaveformViewer* waveformViewer, | 42 | WWaveformViewer* waveformViewer, |
2392 | 40 | const QDomNode& visualNodeCache); | 43 | const QDomNode& visualNodeCache); |
2393 | @@ -62,7 +65,7 @@ | |||
2394 | 62 | 65 | ||
2395 | 63 | void setFrameRate( int frameRate); | 66 | void setFrameRate( int frameRate); |
2396 | 64 | int getFrameRate() const { return m_frameRate;} | 67 | int getFrameRate() const { return m_frameRate;} |
2398 | 65 | double getActualFrameRate() const { return m_actualFrameRate;} | 68 | // bool getVSync() const { return m_vSyncType;} |
2399 | 66 | 69 | ||
2400 | 67 | bool isOpenGLAvailable() const { return m_openGLAvailable;} | 70 | bool isOpenGLAvailable() const { return m_openGLAvailable;} |
2401 | 68 | QString getOpenGLVersion() const { return m_openGLVersion;} | 71 | QString getOpenGLVersion() const { return m_openGLVersion;} |
2402 | @@ -85,22 +88,21 @@ | |||
2403 | 85 | void setOverviewNormalized(bool normalize); | 88 | void setOverviewNormalized(bool normalize); |
2404 | 86 | int isOverviewNormalized() const { return m_overviewNormalized;} | 89 | int isOverviewNormalized() const { return m_overviewNormalized;} |
2405 | 87 | 90 | ||
2407 | 88 | const std::vector<WaveformWidgetAbstractHandle> getAvailableTypes() const { return m_waveformWidgetHandles;} | 91 | const QVector<WaveformWidgetAbstractHandle> getAvailableTypes() const { return m_waveformWidgetHandles;} |
2408 | 92 | void getAvailableVSyncTypes(QList<QPair<int, QString > >* list); | ||
2409 | 89 | void destroyWidgets(); | 93 | void destroyWidgets(); |
2410 | 90 | 94 | ||
2411 | 91 | void addTimerListener(QWidget* pWidget); | 95 | void addTimerListener(QWidget* pWidget); |
2412 | 92 | 96 | ||
2416 | 93 | public slots: | 97 | void startVSync(QWidget *parent); |
2417 | 94 | void start(); | 98 | void setVSyncType(int vsType); |
2418 | 95 | void stop(); | 99 | int getVSyncType(); |
2419 | 96 | 100 | ||
2420 | 97 | void notifyZoomChange(WWaveformViewer *viewer); | 101 | void notifyZoomChange(WWaveformViewer *viewer); |
2421 | 98 | 102 | ||
2422 | 99 | signals: | 103 | signals: |
2423 | 100 | void waveformUpdateTick(); | 104 | void waveformUpdateTick(); |
2427 | 101 | 105 | void waveformMeasured(float frameRate, int rtErrorCnt); | |
2425 | 102 | protected: | ||
2426 | 103 | void timerEvent(QTimerEvent *timerEvent); | ||
2428 | 104 | 106 | ||
2429 | 105 | protected: | 107 | protected: |
2430 | 106 | WaveformWidgetFactory(); | 108 | WaveformWidgetFactory(); |
2431 | @@ -110,6 +112,7 @@ | |||
2432 | 110 | 112 | ||
2433 | 111 | private slots: | 113 | private slots: |
2434 | 112 | void refresh(); | 114 | void refresh(); |
2435 | 115 | void postRefresh(); | ||
2436 | 113 | 116 | ||
2437 | 114 | private: | 117 | private: |
2438 | 115 | WaveformWidgetType::Type autoChooseWidgetType() const; | 118 | WaveformWidgetType::Type autoChooseWidgetType() const; |
2439 | @@ -118,10 +121,11 @@ | |||
2440 | 118 | int findIndexOf( WWaveformViewer* viewer) const; | 121 | int findIndexOf( WWaveformViewer* viewer) const; |
2441 | 119 | 122 | ||
2442 | 120 | //All type of available widgets | 123 | //All type of available widgets |
2444 | 121 | std::vector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles; | 124 | |
2445 | 125 | QVector<WaveformWidgetAbstractHandle> m_waveformWidgetHandles; | ||
2446 | 122 | 126 | ||
2447 | 123 | //Currently in use widgets/visual/node | 127 | //Currently in use widgets/visual/node |
2449 | 124 | std::vector<WaveformWidgetHolder> m_waveformWidgetHolders; | 128 | QVector<WaveformWidgetHolder> m_waveformWidgetHolders; |
2450 | 125 | 129 | ||
2451 | 126 | WaveformWidgetType::Type m_type; | 130 | WaveformWidgetType::Type m_type; |
2452 | 127 | 131 | ||
2453 | @@ -139,10 +143,17 @@ | |||
2454 | 139 | QString m_openGLVersion; | 143 | QString m_openGLVersion; |
2455 | 140 | bool m_openGLShaderAvailable; | 144 | bool m_openGLShaderAvailable; |
2456 | 141 | 145 | ||
2457 | 146 | VSyncThread* m_vsyncThread; | ||
2458 | 147 | |||
2459 | 142 | //Debug | 148 | //Debug |
2462 | 143 | QTime* m_time; | 149 | QTime m_time; |
2463 | 144 | int m_lastFrameTime; | 150 | QTime m_delayTime; |
2464 | 151 | float m_frameCnt; | ||
2465 | 152 | int m_lastRenderDuration; | ||
2466 | 145 | double m_actualFrameRate; | 153 | double m_actualFrameRate; |
2467 | 154 | double m_minimumFrameRate; | ||
2468 | 155 | double m_maximumlFrameRate; | ||
2469 | 156 | int m_vSyncType; | ||
2470 | 146 | }; | 157 | }; |
2471 | 147 | 158 | ||
2472 | 148 | #endif // WAVEFORMWIDGETFACTORY_H | 159 | #endif // WAVEFORMWIDGETFACTORY_H |
2473 | 149 | 160 | ||
2474 | === modified file 'mixxx/src/waveform/widgets/emptywaveformwidget.cpp' | |||
2475 | --- mixxx/src/waveform/widgets/emptywaveformwidget.cpp 2012-09-19 21:04:53 +0000 | |||
2476 | +++ mixxx/src/waveform/widgets/emptywaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
2477 | @@ -25,6 +25,12 @@ | |||
2478 | 25 | } | 25 | } |
2479 | 26 | 26 | ||
2480 | 27 | void EmptyWaveformWidget::paintEvent(QPaintEvent* event) { | 27 | void EmptyWaveformWidget::paintEvent(QPaintEvent* event) { |
2481 | 28 | // Only render if Qt thinks it is required | ||
2482 | 28 | QPainter painter(this); | 29 | QPainter painter(this); |
2483 | 29 | draw(&painter,event); | 30 | draw(&painter,event); |
2484 | 30 | } | 31 | } |
2485 | 32 | |||
2486 | 33 | int EmptyWaveformWidget::render() { | ||
2487 | 34 | // skip update every frame | ||
2488 | 35 | return 0; | ||
2489 | 36 | } | ||
2490 | 31 | 37 | ||
2491 | === modified file 'mixxx/src/waveform/widgets/emptywaveformwidget.h' | |||
2492 | --- mixxx/src/waveform/widgets/emptywaveformwidget.h 2012-09-19 21:04:53 +0000 | |||
2493 | +++ mixxx/src/waveform/widgets/emptywaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
2494 | @@ -18,13 +18,14 @@ | |||
2495 | 18 | static inline QString getWaveformWidgetName() { return tr("Empty"); } | 18 | static inline QString getWaveformWidgetName() { return tr("Empty"); } |
2496 | 19 | static inline bool useOpenGl() { return false; } | 19 | static inline bool useOpenGl() { return false; } |
2497 | 20 | static inline bool useOpenGLShaders() { return false; } | 20 | static inline bool useOpenGLShaders() { return false; } |
2498 | 21 | static inline bool developerOnly() { return false; } | ||
2499 | 21 | 22 | ||
2500 | 22 | protected: | 23 | protected: |
2501 | 23 | virtual void castToQWidget(); | 24 | virtual void castToQWidget(); |
2502 | 24 | virtual void paintEvent(QPaintEvent* event); | 25 | virtual void paintEvent(QPaintEvent* event); |
2503 | 26 | virtual int render(); | ||
2504 | 25 | 27 | ||
2505 | 26 | private: | 28 | private: |
2506 | 27 | EmptyWaveformWidget() {} | ||
2507 | 28 | EmptyWaveformWidget(const char* group, QWidget* parent); | 29 | EmptyWaveformWidget(const char* group, QWidget* parent); |
2508 | 29 | friend class WaveformWidgetFactory; | 30 | friend class WaveformWidgetFactory; |
2509 | 30 | }; | 31 | }; |
2510 | 31 | 32 | ||
2511 | === modified file 'mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp' | |||
2512 | --- mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp 2013-01-04 20:29:33 +0000 | |||
2513 | +++ mixxx/src/waveform/widgets/glsimplewaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
2514 | @@ -13,6 +13,8 @@ | |||
2515 | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" |
2516 | 14 | #include "waveform/renderers/waveformrenderbeat.h" | 14 | #include "waveform/renderers/waveformrenderbeat.h" |
2517 | 15 | 15 | ||
2518 | 16 | #include "util/performancetimer.h" | ||
2519 | 17 | |||
2520 | 16 | GLSimpleWaveformWidget::GLSimpleWaveformWidget( const char* group, QWidget* parent) | 18 | GLSimpleWaveformWidget::GLSimpleWaveformWidget( const char* group, QWidget* parent) |
2521 | 17 | : QGLWidget(parent, SharedGLContext::getWidget()), | 19 | : QGLWidget(parent, SharedGLContext::getWidget()), |
2522 | 18 | WaveformWidgetAbstract(group) { | 20 | WaveformWidgetAbstract(group) { |
2523 | @@ -49,11 +51,24 @@ | |||
2524 | 49 | } | 51 | } |
2525 | 50 | 52 | ||
2526 | 51 | void GLSimpleWaveformWidget::paintEvent( QPaintEvent* event) { | 53 | void GLSimpleWaveformWidget::paintEvent( QPaintEvent* event) { |
2530 | 52 | if (QGLContext::currentContext() != context()) { | 54 | Q_UNUSED(event); |
2531 | 53 | makeCurrent(); | 55 | } |
2532 | 54 | } | 56 | |
2533 | 57 | int GLSimpleWaveformWidget::render() { | ||
2534 | 58 | PerformanceTimer timer; | ||
2535 | 59 | int t1; | ||
2536 | 60 | //int t2, t3; | ||
2537 | 61 | timer.start(); | ||
2538 | 62 | // QPainter makes QGLContext::currentContext() == context() | ||
2539 | 63 | // this may delayed until previous buffer swap finished | ||
2540 | 55 | QPainter painter(this); | 64 | QPainter painter(this); |
2542 | 56 | draw(&painter,event); | 65 | t1 = timer.restart(); |
2543 | 66 | draw(&painter, NULL); | ||
2544 | 67 | //t2 = timer.restart(); | ||
2545 | 68 | //glFinish(); | ||
2546 | 69 | //t3 = timer.restart(); | ||
2547 | 70 | //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3; | ||
2548 | 71 | return t1 / 1000; // return timer for painter setup | ||
2549 | 57 | } | 72 | } |
2550 | 58 | 73 | ||
2551 | 59 | void GLSimpleWaveformWidget::postRender() { | 74 | void GLSimpleWaveformWidget::postRender() { |
2552 | 60 | 75 | ||
2553 | === modified file 'mixxx/src/waveform/widgets/glsimplewaveformwidget.h' | |||
2554 | --- mixxx/src/waveform/widgets/glsimplewaveformwidget.h 2012-09-19 21:04:53 +0000 | |||
2555 | +++ mixxx/src/waveform/widgets/glsimplewaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
2556 | @@ -11,19 +11,20 @@ | |||
2557 | 11 | GLSimpleWaveformWidget(const char* group, QWidget* parent); | 11 | GLSimpleWaveformWidget(const char* group, QWidget* parent); |
2558 | 12 | virtual ~GLSimpleWaveformWidget(); | 12 | virtual ~GLSimpleWaveformWidget(); |
2559 | 13 | 13 | ||
2561 | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform;} | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform; } |
2562 | 15 | 15 | ||
2566 | 16 | static inline QString getWaveformWidgetName() { return tr("Simple");} | 16 | static inline QString getWaveformWidgetName() { return tr("Simple"); } |
2567 | 17 | static inline bool useOpenGl() { return true;} | 17 | static inline bool useOpenGl() { return true; } |
2568 | 18 | static inline bool useOpenGLShaders() { return false;} | 18 | static inline bool useOpenGLShaders() { return false; } |
2569 | 19 | static inline bool developerOnly() { return false; } | ||
2570 | 19 | 20 | ||
2571 | 20 | protected: | 21 | protected: |
2572 | 21 | virtual void castToQWidget(); | 22 | virtual void castToQWidget(); |
2573 | 22 | virtual void paintEvent(QPaintEvent* event); | 23 | virtual void paintEvent(QPaintEvent* event); |
2574 | 23 | virtual void postRender(); | 24 | virtual void postRender(); |
2575 | 25 | virtual int render(); | ||
2576 | 24 | 26 | ||
2577 | 25 | private: | 27 | private: |
2578 | 26 | GLSimpleWaveformWidget() {} | ||
2579 | 27 | friend class WaveformWidgetFactory; | 28 | friend class WaveformWidgetFactory; |
2580 | 28 | }; | 29 | }; |
2581 | 29 | #endif // GLSIMPLEWAVEFORMWIDGET_H | 30 | #endif // GLSIMPLEWAVEFORMWIDGET_H |
2582 | 30 | 31 | ||
2583 | === modified file 'mixxx/src/waveform/widgets/glslwaveformwidget.cpp' | |||
2584 | --- mixxx/src/waveform/widgets/glslwaveformwidget.cpp 2013-01-04 20:29:33 +0000 | |||
2585 | +++ mixxx/src/waveform/widgets/glslwaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
2586 | @@ -13,6 +13,8 @@ | |||
2587 | 13 | #include "waveform/renderers/waveformrenderbeat.h" | 13 | #include "waveform/renderers/waveformrenderbeat.h" |
2588 | 14 | #include "sharedglcontext.h" | 14 | #include "sharedglcontext.h" |
2589 | 15 | 15 | ||
2590 | 16 | #include "util/performancetimer.h" | ||
2591 | 17 | |||
2592 | 16 | GLSLWaveformWidget::GLSLWaveformWidget( const char* group, QWidget* parent) | 18 | GLSLWaveformWidget::GLSLWaveformWidget( const char* group, QWidget* parent) |
2593 | 17 | : QGLWidget(parent, SharedGLContext::getWidget()), | 19 | : QGLWidget(parent, SharedGLContext::getWidget()), |
2594 | 18 | WaveformWidgetAbstract(group) { | 20 | WaveformWidgetAbstract(group) { |
2595 | @@ -48,10 +50,24 @@ | |||
2596 | 48 | } | 50 | } |
2597 | 49 | 51 | ||
2598 | 50 | void GLSLWaveformWidget::paintEvent( QPaintEvent* event) { | 52 | void GLSLWaveformWidget::paintEvent( QPaintEvent* event) { |
2600 | 51 | makeCurrent(); | 53 | Q_UNUSED(event); |
2601 | 54 | } | ||
2602 | 55 | |||
2603 | 56 | int GLSLWaveformWidget::render() { | ||
2604 | 57 | PerformanceTimer timer; | ||
2605 | 58 | int t1; | ||
2606 | 59 | //int t2, t3; | ||
2607 | 60 | timer.start(); | ||
2608 | 61 | // QPainter makes QGLContext::currentContext() == context() | ||
2609 | 62 | // this may delayed until previous buffer swap finished | ||
2610 | 52 | QPainter painter(this); | 63 | QPainter painter(this); |
2613 | 53 | draw(&painter,event); | 64 | t1 = timer.restart(); |
2614 | 54 | QGLWidget::swapBuffers(); | 65 | draw(&painter, NULL); |
2615 | 66 | //t2 = timer.restart(); | ||
2616 | 67 | //glFinish(); | ||
2617 | 68 | //t3 = timer.restart(); | ||
2618 | 69 | //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3; | ||
2619 | 70 | return t1 / 1000; // return timer for painter setup | ||
2620 | 55 | } | 71 | } |
2621 | 56 | 72 | ||
2622 | 57 | void GLSLWaveformWidget::resize( int width, int height) { | 73 | void GLSLWaveformWidget::resize( int width, int height) { |
2623 | @@ -67,3 +83,7 @@ | |||
2624 | 67 | signalRenderer_->loadShaders(); | 83 | signalRenderer_->loadShaders(); |
2625 | 68 | } | 84 | } |
2626 | 69 | } | 85 | } |
2627 | 86 | |||
2628 | 87 | void GLSLWaveformWidget::postRender() { | ||
2629 | 88 | swapBuffers(); | ||
2630 | 89 | } | ||
2631 | 70 | 90 | ||
2632 | === modified file 'mixxx/src/waveform/widgets/glslwaveformwidget.h' | |||
2633 | --- mixxx/src/waveform/widgets/glslwaveformwidget.h 2012-12-06 06:35:21 +0000 | |||
2634 | +++ mixxx/src/waveform/widgets/glslwaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
2635 | @@ -13,11 +13,12 @@ | |||
2636 | 13 | GLSLWaveformWidget(const char* group, QWidget* parent); | 13 | GLSLWaveformWidget(const char* group, QWidget* parent); |
2637 | 14 | virtual ~GLSLWaveformWidget(); | 14 | virtual ~GLSLWaveformWidget(); |
2638 | 15 | 15 | ||
2640 | 16 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSLWaveform;} | 16 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSLWaveform; } |
2641 | 17 | 17 | ||
2645 | 18 | static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("experimental");} | 18 | static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("experimental"); } |
2646 | 19 | static inline bool useOpenGl() { return true;} | 19 | static inline bool useOpenGl() { return true; } |
2647 | 20 | static inline bool useOpenGLShaders() { return true;} | 20 | static inline bool useOpenGLShaders() { return true; } |
2648 | 21 | static inline bool developerOnly() { return false; } | ||
2649 | 21 | 22 | ||
2650 | 22 | virtual void resize(int width, int height); | 23 | virtual void resize(int width, int height); |
2651 | 23 | 24 | ||
2652 | @@ -25,11 +26,12 @@ | |||
2653 | 25 | virtual void castToQWidget(); | 26 | virtual void castToQWidget(); |
2654 | 26 | virtual void paintEvent(QPaintEvent* event); | 27 | virtual void paintEvent(QPaintEvent* event); |
2655 | 27 | virtual void mouseDoubleClickEvent(QMouseEvent *); | 28 | virtual void mouseDoubleClickEvent(QMouseEvent *); |
2656 | 29 | virtual void postRender(); | ||
2657 | 30 | virtual int render(); | ||
2658 | 28 | 31 | ||
2659 | 29 | private: | 32 | private: |
2660 | 30 | GLSLWaveformRendererSignal* signalRenderer_; | 33 | GLSLWaveformRendererSignal* signalRenderer_; |
2661 | 31 | 34 | ||
2662 | 32 | GLSLWaveformWidget() {} | ||
2663 | 33 | friend class WaveformWidgetFactory; | 35 | friend class WaveformWidgetFactory; |
2664 | 34 | }; | 36 | }; |
2665 | 35 | 37 | ||
2666 | 36 | 38 | ||
2667 | === added file 'mixxx/src/waveform/widgets/glvsynctestwidget.cpp' | |||
2668 | --- mixxx/src/waveform/widgets/glvsynctestwidget.cpp 1970-01-01 00:00:00 +0000 | |||
2669 | +++ mixxx/src/waveform/widgets/glvsynctestwidget.cpp 2013-05-01 22:08:27 +0000 | |||
2670 | @@ -0,0 +1,75 @@ | |||
2671 | 1 | #include "glvsynctestwidget.h" | ||
2672 | 2 | |||
2673 | 3 | #include <QPainter> | ||
2674 | 4 | |||
2675 | 5 | #include "sharedglcontext.h" | ||
2676 | 6 | #include "waveform/renderers/waveformwidgetrenderer.h" | ||
2677 | 7 | #include "waveform/renderers/waveformrenderbackground.h" | ||
2678 | 8 | #include "waveform/renderers/glwaveformrenderersimplesignal.h" | ||
2679 | 9 | #include "waveform/renderers/glvsynctestrenderer.h" | ||
2680 | 10 | #include "waveform/renderers/waveformrendererpreroll.h" | ||
2681 | 11 | #include "waveform/renderers/waveformrendermark.h" | ||
2682 | 12 | #include "waveform/renderers/waveformrendermarkrange.h" | ||
2683 | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" | ||
2684 | 14 | #include "waveform/renderers/waveformrenderbeat.h" | ||
2685 | 15 | |||
2686 | 16 | #include "util/performancetimer.h" | ||
2687 | 17 | |||
2688 | 18 | GLVSyncTestWidget::GLVSyncTestWidget( const char* group, QWidget* parent) | ||
2689 | 19 | : QGLWidget(parent, SharedGLContext::getWidget()), | ||
2690 | 20 | WaveformWidgetAbstract(group) { | ||
2691 | 21 | |||
2692 | 22 | // addRenderer<WaveformRenderBackground>(); // 172 µs | ||
2693 | 23 | // addRenderer<WaveformRendererEndOfTrack>(); // 677 µs 1145 µs (active) | ||
2694 | 24 | // addRenderer<WaveformRendererPreroll>(); // 652 µs 2034 µs (active) | ||
2695 | 25 | // addRenderer<WaveformRenderMarkRange>(); // 793 µs | ||
2696 | 26 | addRenderer<GLVSyncTestRenderer>(); // 841 µs // 2271 µs | ||
2697 | 27 | // addRenderer<WaveformRenderMark>(); // 711 µs | ||
2698 | 28 | // addRenderer<WaveformRenderBeat>(); // 1183 µs | ||
2699 | 29 | |||
2700 | 30 | setAttribute(Qt::WA_NoSystemBackground); | ||
2701 | 31 | setAttribute(Qt::WA_OpaquePaintEvent); | ||
2702 | 32 | |||
2703 | 33 | setAutoBufferSwap(false); | ||
2704 | 34 | |||
2705 | 35 | if (QGLContext::currentContext() != context()) { | ||
2706 | 36 | makeCurrent(); | ||
2707 | 37 | } | ||
2708 | 38 | m_initSuccess = init(); | ||
2709 | 39 | qDebug() << "GLVSyncTestWidget.isSharing() =" << isSharing(); | ||
2710 | 40 | } | ||
2711 | 41 | |||
2712 | 42 | GLVSyncTestWidget::~GLVSyncTestWidget(){ | ||
2713 | 43 | if (QGLContext::currentContext() != context()) { | ||
2714 | 44 | makeCurrent(); | ||
2715 | 45 | } | ||
2716 | 46 | } | ||
2717 | 47 | |||
2718 | 48 | void GLVSyncTestWidget::castToQWidget() { | ||
2719 | 49 | m_widget = static_cast<QWidget*>(static_cast<QGLWidget*>(this)); | ||
2720 | 50 | } | ||
2721 | 51 | |||
2722 | 52 | void GLVSyncTestWidget::paintEvent( QPaintEvent* event) { | ||
2723 | 53 | Q_UNUSED(event); | ||
2724 | 54 | } | ||
2725 | 55 | |||
2726 | 56 | int GLVSyncTestWidget::render() { | ||
2727 | 57 | PerformanceTimer timer; | ||
2728 | 58 | int t1; | ||
2729 | 59 | //int t2, t3; | ||
2730 | 60 | timer.start(); | ||
2731 | 61 | // QPainter makes QGLContext::currentContext() == context() | ||
2732 | 62 | // this may delayed until previous buffer swap finished | ||
2733 | 63 | QPainter painter(this); | ||
2734 | 64 | t1 = timer.restart(); | ||
2735 | 65 | draw(&painter, NULL); | ||
2736 | 66 | //t2 = timer.restart(); | ||
2737 | 67 | glFinish(); | ||
2738 | 68 | //t3 = timer.restart(); | ||
2739 | 69 | //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3; | ||
2740 | 70 | return t1 / 1000; // return timer for painter setup | ||
2741 | 71 | } | ||
2742 | 72 | |||
2743 | 73 | void GLVSyncTestWidget::postRender() { | ||
2744 | 74 | QGLWidget::swapBuffers(); | ||
2745 | 75 | } | ||
2746 | 0 | 76 | ||
2747 | === added file 'mixxx/src/waveform/widgets/glvsynctestwidget.h' | |||
2748 | --- mixxx/src/waveform/widgets/glvsynctestwidget.h 1970-01-01 00:00:00 +0000 | |||
2749 | +++ mixxx/src/waveform/widgets/glvsynctestwidget.h 2013-05-01 22:08:27 +0000 | |||
2750 | @@ -0,0 +1,30 @@ | |||
2751 | 1 | #ifndef GLVSYNCTESTWIDGET_H | ||
2752 | 2 | #define GLVSYNCTESTWIDGET_H | ||
2753 | 3 | |||
2754 | 4 | #include <QGLWidget> | ||
2755 | 5 | |||
2756 | 6 | #include "waveformwidgetabstract.h" | ||
2757 | 7 | |||
2758 | 8 | class GLVSyncTestWidget : public QGLWidget, public WaveformWidgetAbstract { | ||
2759 | 9 | Q_OBJECT | ||
2760 | 10 | public: | ||
2761 | 11 | GLVSyncTestWidget(const char* group, QWidget* parent); | ||
2762 | 12 | virtual ~GLVSyncTestWidget(); | ||
2763 | 13 | |||
2764 | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLVSyncTest; } | ||
2765 | 15 | |||
2766 | 16 | static inline QString getWaveformWidgetName() { return tr("VSyncTest"); } | ||
2767 | 17 | static inline bool useOpenGl() { return true; } | ||
2768 | 18 | static inline bool useOpenGLShaders() { return false; } | ||
2769 | 19 | static inline bool developerOnly() { return true; } | ||
2770 | 20 | |||
2771 | 21 | protected: | ||
2772 | 22 | virtual void castToQWidget(); | ||
2773 | 23 | virtual void paintEvent(QPaintEvent* event); | ||
2774 | 24 | virtual void postRender(); | ||
2775 | 25 | virtual int render(); | ||
2776 | 26 | |||
2777 | 27 | private: | ||
2778 | 28 | friend class WaveformWidgetFactory; | ||
2779 | 29 | }; | ||
2780 | 30 | #endif // GLVSYNCTESTWIDGET_H | ||
2781 | 0 | 31 | ||
2782 | === modified file 'mixxx/src/waveform/widgets/glwaveformwidget.cpp' | |||
2783 | --- mixxx/src/waveform/widgets/glwaveformwidget.cpp 2013-01-04 20:29:33 +0000 | |||
2784 | +++ mixxx/src/waveform/widgets/glwaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
2785 | @@ -13,6 +13,7 @@ | |||
2786 | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" |
2787 | 14 | #include "waveform/renderers/waveformrenderbeat.h" | 14 | #include "waveform/renderers/waveformrenderbeat.h" |
2788 | 15 | #include "sharedglcontext.h" | 15 | #include "sharedglcontext.h" |
2789 | 16 | #include "util/performancetimer.h" | ||
2790 | 16 | 17 | ||
2791 | 17 | GLWaveformWidget::GLWaveformWidget( const char* group, QWidget* parent) | 18 | GLWaveformWidget::GLWaveformWidget( const char* group, QWidget* parent) |
2792 | 18 | : QGLWidget(parent, SharedGLContext::getWidget()), | 19 | : QGLWidget(parent, SharedGLContext::getWidget()), |
2793 | @@ -48,11 +49,24 @@ | |||
2794 | 48 | } | 49 | } |
2795 | 49 | 50 | ||
2796 | 50 | void GLWaveformWidget::paintEvent( QPaintEvent* event) { | 51 | void GLWaveformWidget::paintEvent( QPaintEvent* event) { |
2800 | 51 | if (QGLContext::currentContext() != context()) { | 52 | Q_UNUSED(event); |
2801 | 52 | makeCurrent(); | 53 | } |
2802 | 53 | } | 54 | |
2803 | 55 | int GLWaveformWidget::render() { | ||
2804 | 56 | PerformanceTimer timer; | ||
2805 | 57 | int t1; | ||
2806 | 58 | //int t2, t3; | ||
2807 | 59 | timer.start(); | ||
2808 | 60 | // QPainter makes QGLContext::currentContext() == context() | ||
2809 | 61 | // this may delayed until previous buffer swap finished | ||
2810 | 54 | QPainter painter(this); | 62 | QPainter painter(this); |
2812 | 55 | draw(&painter, event); | 63 | t1 = timer.restart(); |
2813 | 64 | draw(&painter, NULL); | ||
2814 | 65 | //t2 = timer.restart(); | ||
2815 | 66 | // glFinish(); | ||
2816 | 67 | //t3 = timer.restart(); | ||
2817 | 68 | //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3; | ||
2818 | 69 | return t1 / 1000; // return timer for painter setup | ||
2819 | 56 | } | 70 | } |
2820 | 57 | 71 | ||
2821 | 58 | void GLWaveformWidget::postRender() { | 72 | void GLWaveformWidget::postRender() { |
2822 | 59 | 73 | ||
2823 | === modified file 'mixxx/src/waveform/widgets/glwaveformwidget.h' | |||
2824 | --- mixxx/src/waveform/widgets/glwaveformwidget.h 2012-12-06 06:35:21 +0000 | |||
2825 | +++ mixxx/src/waveform/widgets/glwaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
2826 | @@ -13,17 +13,18 @@ | |||
2827 | 13 | 13 | ||
2828 | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLWaveform; } | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLWaveform; } |
2829 | 15 | 15 | ||
2833 | 16 | static inline QString getWaveformWidgetName() { return tr("Filtered");} | 16 | static inline QString getWaveformWidgetName() { return tr("Filtered"); } |
2834 | 17 | static inline bool useOpenGl() { return true;} | 17 | static inline bool useOpenGl() { return true; } |
2835 | 18 | static inline bool useOpenGLShaders() { return false;} | 18 | static inline bool useOpenGLShaders() { return false; } |
2836 | 19 | static inline bool developerOnly() { return false; } | ||
2837 | 19 | 20 | ||
2838 | 20 | protected: | 21 | protected: |
2839 | 21 | virtual void castToQWidget(); | 22 | virtual void castToQWidget(); |
2840 | 22 | virtual void paintEvent(QPaintEvent* event); | 23 | virtual void paintEvent(QPaintEvent* event); |
2841 | 23 | virtual void postRender(); | 24 | virtual void postRender(); |
2842 | 25 | virtual int render(); | ||
2843 | 24 | 26 | ||
2844 | 25 | private: | 27 | private: |
2845 | 26 | GLWaveformWidget() {} | ||
2846 | 27 | friend class WaveformWidgetFactory; | 28 | friend class WaveformWidgetFactory; |
2847 | 28 | }; | 29 | }; |
2848 | 29 | 30 | ||
2849 | 30 | 31 | ||
2850 | === added file 'mixxx/src/waveform/widgets/hsvwaveformwidget.cpp' | |||
2851 | --- mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 1970-01-01 00:00:00 +0000 | |||
2852 | +++ mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
2853 | @@ -0,0 +1,41 @@ | |||
2854 | 1 | #include "hsvwaveformwidget.h" | ||
2855 | 2 | |||
2856 | 3 | #include <QPainter> | ||
2857 | 4 | |||
2858 | 5 | #include "waveform/renderers/waveformwidgetrenderer.h" | ||
2859 | 6 | #include "waveform/renderers/waveformrenderbackground.h" | ||
2860 | 7 | #include "waveform/renderers/waveformrendermark.h" | ||
2861 | 8 | #include "waveform/renderers/waveformrendermarkrange.h" | ||
2862 | 9 | #include "waveform/renderers/waveformrendererhsv.h" | ||
2863 | 10 | #include "waveform/renderers/waveformrendererpreroll.h" | ||
2864 | 11 | #include "waveform/renderers/waveformrendererendoftrack.h" | ||
2865 | 12 | #include "waveform/renderers/waveformrenderbeat.h" | ||
2866 | 13 | |||
2867 | 14 | HSVWaveformWidget::HSVWaveformWidget( const char* group, QWidget* parent) | ||
2868 | 15 | : QWidget(parent), | ||
2869 | 16 | WaveformWidgetAbstract(group) { | ||
2870 | 17 | addRenderer<WaveformRenderBackground>(); | ||
2871 | 18 | addRenderer<WaveformRendererEndOfTrack>(); | ||
2872 | 19 | addRenderer<WaveformRendererPreroll>(); | ||
2873 | 20 | addRenderer<WaveformRenderMarkRange>(); | ||
2874 | 21 | addRenderer<WaveformRendererHSV>(); | ||
2875 | 22 | addRenderer<WaveformRenderMark>(); | ||
2876 | 23 | addRenderer<WaveformRenderBeat>(); | ||
2877 | 24 | |||
2878 | 25 | setAttribute(Qt::WA_NoSystemBackground); | ||
2879 | 26 | setAttribute(Qt::WA_OpaquePaintEvent); | ||
2880 | 27 | |||
2881 | 28 | m_initSuccess = init(); | ||
2882 | 29 | } | ||
2883 | 30 | |||
2884 | 31 | HSVWaveformWidget::~HSVWaveformWidget() { | ||
2885 | 32 | } | ||
2886 | 33 | |||
2887 | 34 | void HSVWaveformWidget::castToQWidget() { | ||
2888 | 35 | m_widget = static_cast<QWidget*>(this); | ||
2889 | 36 | } | ||
2890 | 37 | |||
2891 | 38 | void HSVWaveformWidget::paintEvent( QPaintEvent* event) { | ||
2892 | 39 | QPainter painter(this); | ||
2893 | 40 | draw(&painter,event); | ||
2894 | 41 | } | ||
2895 | 0 | 42 | ||
2896 | === removed file 'mixxx/src/waveform/widgets/hsvwaveformwidget.cpp' | |||
2897 | --- mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 2013-01-04 20:29:33 +0000 | |||
2898 | +++ mixxx/src/waveform/widgets/hsvwaveformwidget.cpp 1970-01-01 00:00:00 +0000 | |||
2899 | @@ -1,41 +0,0 @@ | |||
2900 | 1 | #include "hsvwaveformwidget.h" | ||
2901 | 2 | |||
2902 | 3 | #include <QPainter> | ||
2903 | 4 | |||
2904 | 5 | #include "waveform/renderers/waveformwidgetrenderer.h" | ||
2905 | 6 | #include "waveform/renderers/waveformrenderbackground.h" | ||
2906 | 7 | #include "waveform/renderers/waveformrendermark.h" | ||
2907 | 8 | #include "waveform/renderers/waveformrendermarkrange.h" | ||
2908 | 9 | #include "waveform/renderers/waveformrendererhsv.h" | ||
2909 | 10 | #include "waveform/renderers/waveformrendererpreroll.h" | ||
2910 | 11 | #include "waveform/renderers/waveformrendererendoftrack.h" | ||
2911 | 12 | #include "waveform/renderers/waveformrenderbeat.h" | ||
2912 | 13 | |||
2913 | 14 | HSVWaveformWidget::HSVWaveformWidget( const char* group, QWidget* parent) | ||
2914 | 15 | : QWidget(parent), | ||
2915 | 16 | WaveformWidgetAbstract(group) { | ||
2916 | 17 | addRenderer<WaveformRenderBackground>(); | ||
2917 | 18 | addRenderer<WaveformRendererEndOfTrack>(); | ||
2918 | 19 | addRenderer<WaveformRendererPreroll>(); | ||
2919 | 20 | addRenderer<WaveformRenderMarkRange>(); | ||
2920 | 21 | addRenderer<WaveformRendererHSV>(); | ||
2921 | 22 | addRenderer<WaveformRenderBeat>(); | ||
2922 | 23 | addRenderer<WaveformRenderMark>(); | ||
2923 | 24 | |||
2924 | 25 | setAttribute(Qt::WA_NoSystemBackground); | ||
2925 | 26 | setAttribute(Qt::WA_OpaquePaintEvent); | ||
2926 | 27 | |||
2927 | 28 | m_initSuccess = init(); | ||
2928 | 29 | } | ||
2929 | 30 | |||
2930 | 31 | HSVWaveformWidget::~HSVWaveformWidget() { | ||
2931 | 32 | } | ||
2932 | 33 | |||
2933 | 34 | void HSVWaveformWidget::castToQWidget() { | ||
2934 | 35 | m_widget = static_cast<QWidget*>(this); | ||
2935 | 36 | } | ||
2936 | 37 | |||
2937 | 38 | void HSVWaveformWidget::paintEvent( QPaintEvent* event) { | ||
2938 | 39 | QPainter painter(this); | ||
2939 | 40 | draw(&painter,event); | ||
2940 | 41 | } | ||
2941 | 42 | 0 | ||
2942 | === added file 'mixxx/src/waveform/widgets/hsvwaveformwidget.h' | |||
2943 | --- mixxx/src/waveform/widgets/hsvwaveformwidget.h 1970-01-01 00:00:00 +0000 | |||
2944 | +++ mixxx/src/waveform/widgets/hsvwaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
2945 | @@ -0,0 +1,29 @@ | |||
2946 | 1 | #ifndef HSVWAVEFORMWIDGET_H | ||
2947 | 2 | #define HSVWAVEFORMWIDGET_H | ||
2948 | 3 | |||
2949 | 4 | #include <QWidget> | ||
2950 | 5 | |||
2951 | 6 | #include "waveformwidgetabstract.h" | ||
2952 | 7 | |||
2953 | 8 | class HSVWaveformWidget : public QWidget, public WaveformWidgetAbstract { | ||
2954 | 9 | Q_OBJECT | ||
2955 | 10 | public: | ||
2956 | 11 | virtual ~HSVWaveformWidget(); | ||
2957 | 12 | |||
2958 | 13 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::HSVWaveform; } | ||
2959 | 14 | |||
2960 | 15 | static inline QString getWaveformWidgetName() { return tr("HSV"); } | ||
2961 | 16 | static inline bool useOpenGl() { return false; } | ||
2962 | 17 | static inline bool useOpenGLShaders() { return false; } | ||
2963 | 18 | static inline bool developerOnly() { return false; } | ||
2964 | 19 | |||
2965 | 20 | protected: | ||
2966 | 21 | virtual void castToQWidget(); | ||
2967 | 22 | virtual void paintEvent(QPaintEvent* event); | ||
2968 | 23 | |||
2969 | 24 | private: | ||
2970 | 25 | HSVWaveformWidget(const char* group, QWidget* parent); | ||
2971 | 26 | friend class WaveformWidgetFactory; | ||
2972 | 27 | }; | ||
2973 | 28 | |||
2974 | 29 | #endif // HSVWAVEFORMWIDGET_H | ||
2975 | 0 | 30 | ||
2976 | === removed file 'mixxx/src/waveform/widgets/hsvwaveformwidget.h' | |||
2977 | --- mixxx/src/waveform/widgets/hsvwaveformwidget.h 2012-12-14 01:26:04 +0000 | |||
2978 | +++ mixxx/src/waveform/widgets/hsvwaveformwidget.h 1970-01-01 00:00:00 +0000 | |||
2979 | @@ -1,29 +0,0 @@ | |||
2980 | 1 | #ifndef HSVWAVEFORMWIDGET_H | ||
2981 | 2 | #define HSVWAVEFORMWIDGET_H | ||
2982 | 3 | |||
2983 | 4 | #include <QWidget> | ||
2984 | 5 | |||
2985 | 6 | #include "waveformwidgetabstract.h" | ||
2986 | 7 | |||
2987 | 8 | class HSVWaveformWidget : public QWidget, public WaveformWidgetAbstract { | ||
2988 | 9 | Q_OBJECT | ||
2989 | 10 | public: | ||
2990 | 11 | virtual ~HSVWaveformWidget(); | ||
2991 | 12 | |||
2992 | 13 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::HSVWaveform;} | ||
2993 | 14 | |||
2994 | 15 | static inline QString getWaveformWidgetName() { return tr("HSV");} | ||
2995 | 16 | static inline bool useOpenGl() { return false;} | ||
2996 | 17 | static inline bool useOpenGLShaders() { return false;} | ||
2997 | 18 | |||
2998 | 19 | protected: | ||
2999 | 20 | virtual void castToQWidget(); | ||
3000 | 21 | virtual void paintEvent(QPaintEvent* event); | ||
3001 | 22 | |||
3002 | 23 | private: | ||
3003 | 24 | HSVWaveformWidget() {} | ||
3004 | 25 | HSVWaveformWidget(const char* group, QWidget* parent); | ||
3005 | 26 | friend class WaveformWidgetFactory; | ||
3006 | 27 | }; | ||
3007 | 28 | |||
3008 | 29 | #endif // HSVWAVEFORMWIDGET_H | ||
3009 | 30 | 0 | ||
3010 | === modified file 'mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp' | |||
3011 | --- mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp 2013-01-31 19:48:57 +0000 | |||
3012 | +++ mixxx/src/waveform/widgets/qtsimplewaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
3013 | @@ -13,6 +13,8 @@ | |||
3014 | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" | 13 | #include "waveform/renderers/waveformrendererendoftrack.h" |
3015 | 14 | #include "waveform/renderers/waveformrenderbeat.h" | 14 | #include "waveform/renderers/waveformrenderbeat.h" |
3016 | 15 | 15 | ||
3017 | 16 | #include "util/performancetimer.h" | ||
3018 | 17 | |||
3019 | 16 | QtSimpleWaveformWidget::QtSimpleWaveformWidget( const char* group, QWidget* parent) | 18 | QtSimpleWaveformWidget::QtSimpleWaveformWidget( const char* group, QWidget* parent) |
3020 | 17 | : QGLWidget(parent, SharedGLContext::getWidget()), | 19 | : QGLWidget(parent, SharedGLContext::getWidget()), |
3021 | 18 | WaveformWidgetAbstract(group) { | 20 | WaveformWidgetAbstract(group) { |
3022 | @@ -49,11 +51,24 @@ | |||
3023 | 49 | } | 51 | } |
3024 | 50 | 52 | ||
3025 | 51 | void QtSimpleWaveformWidget::paintEvent(QPaintEvent* event) { | 53 | void QtSimpleWaveformWidget::paintEvent(QPaintEvent* event) { |
3029 | 52 | if (QGLContext::currentContext() != context()) { | 54 | Q_UNUSED(event); |
3030 | 53 | makeCurrent(); | 55 | } |
3031 | 54 | } | 56 | |
3032 | 57 | int QtSimpleWaveformWidget::render() { | ||
3033 | 58 | PerformanceTimer timer; | ||
3034 | 59 | int t1; | ||
3035 | 60 | //int t2, t3; | ||
3036 | 61 | timer.start(); | ||
3037 | 62 | // QPainter makes QGLContext::currentContext() == context() | ||
3038 | 63 | // this may delayed until previous buffer swap finished | ||
3039 | 55 | QPainter painter(this); | 64 | QPainter painter(this); |
3041 | 56 | draw(&painter, event); | 65 | t1 = timer.restart(); |
3042 | 66 | draw(&painter, NULL); | ||
3043 | 67 | //t2 = timer.restart(); | ||
3044 | 68 | //glFinish(); | ||
3045 | 69 | //t3 = timer.restart(); | ||
3046 | 70 | //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3; | ||
3047 | 71 | return t1/1000; // return timer for painter setup | ||
3048 | 57 | } | 72 | } |
3049 | 58 | 73 | ||
3050 | 59 | void QtSimpleWaveformWidget::postRender() { | 74 | void QtSimpleWaveformWidget::postRender() { |
3051 | 60 | 75 | ||
3052 | === modified file 'mixxx/src/waveform/widgets/qtsimplewaveformwidget.h' | |||
3053 | --- mixxx/src/waveform/widgets/qtsimplewaveformwidget.h 2012-09-19 21:04:53 +0000 | |||
3054 | +++ mixxx/src/waveform/widgets/qtsimplewaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
3055 | @@ -12,19 +12,20 @@ | |||
3056 | 12 | virtual ~QtSimpleWaveformWidget(); | 12 | virtual ~QtSimpleWaveformWidget(); |
3057 | 13 | 13 | ||
3058 | 14 | 14 | ||
3060 | 15 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform;} | 15 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::GLSimpleWaveform; } |
3061 | 16 | 16 | ||
3065 | 17 | static inline QString getWaveformWidgetName() { return tr("Simple") + " - Qt";} | 17 | static inline QString getWaveformWidgetName() { return tr("Simple") + " - Qt"; } |
3066 | 18 | static inline bool useOpenGl() { return true;} | 18 | static inline bool useOpenGl() { return true; } |
3067 | 19 | static inline bool useOpenGLShaders() { return false;} | 19 | static inline bool useOpenGLShaders() { return false; } |
3068 | 20 | static inline bool developerOnly() { return false; } | ||
3069 | 20 | 21 | ||
3070 | 21 | protected: | 22 | protected: |
3071 | 22 | virtual void castToQWidget(); | 23 | virtual void castToQWidget(); |
3072 | 23 | virtual void paintEvent(QPaintEvent* event); | 24 | virtual void paintEvent(QPaintEvent* event); |
3073 | 24 | virtual void postRender(); | 25 | virtual void postRender(); |
3074 | 26 | virtual int render(); | ||
3075 | 25 | 27 | ||
3076 | 26 | private: | 28 | private: |
3077 | 27 | QtSimpleWaveformWidget() {} | ||
3078 | 28 | friend class WaveformWidgetFactory; | 29 | friend class WaveformWidgetFactory; |
3079 | 29 | }; | 30 | }; |
3080 | 30 | 31 | ||
3081 | 31 | 32 | ||
3082 | === modified file 'mixxx/src/waveform/widgets/qtwaveformwidget.cpp' | |||
3083 | --- mixxx/src/waveform/widgets/qtwaveformwidget.cpp 2013-01-04 20:29:33 +0000 | |||
3084 | +++ mixxx/src/waveform/widgets/qtwaveformwidget.cpp 2013-05-01 22:08:27 +0000 | |||
3085 | @@ -14,6 +14,8 @@ | |||
3086 | 14 | #include "waveform/renderers/waveformrenderbeat.h" | 14 | #include "waveform/renderers/waveformrenderbeat.h" |
3087 | 15 | #include "sharedglcontext.h" | 15 | #include "sharedglcontext.h" |
3088 | 16 | 16 | ||
3089 | 17 | #include "util/performancetimer.h" | ||
3090 | 18 | |||
3091 | 17 | QtWaveformWidget::QtWaveformWidget( const char* group, QWidget* parent) | 19 | QtWaveformWidget::QtWaveformWidget( const char* group, QWidget* parent) |
3092 | 18 | : QGLWidget(parent, SharedGLContext::getWidget()), | 20 | : QGLWidget(parent, SharedGLContext::getWidget()), |
3093 | 19 | WaveformWidgetAbstract(group) { | 21 | WaveformWidgetAbstract(group) { |
3094 | @@ -47,11 +49,24 @@ | |||
3095 | 47 | } | 49 | } |
3096 | 48 | 50 | ||
3097 | 49 | void QtWaveformWidget::paintEvent( QPaintEvent* event) { | 51 | void QtWaveformWidget::paintEvent( QPaintEvent* event) { |
3101 | 50 | if (QGLContext::currentContext() != context()) { | 52 | Q_UNUSED(event); |
3102 | 51 | makeCurrent(); | 53 | } |
3103 | 52 | } | 54 | |
3104 | 55 | int QtWaveformWidget::render() { | ||
3105 | 56 | PerformanceTimer timer; | ||
3106 | 57 | int t1; | ||
3107 | 58 | //int t2, t3; | ||
3108 | 59 | timer.start(); | ||
3109 | 60 | // QPainter makes QGLContext::currentContext() == context() | ||
3110 | 61 | // this may delayed until previous buffer swap finished | ||
3111 | 53 | QPainter painter(this); | 62 | QPainter painter(this); |
3113 | 54 | draw(&painter, event); | 63 | t1 = timer.restart(); |
3114 | 64 | draw(&painter, NULL); | ||
3115 | 65 | //t2 = timer.restart(); | ||
3116 | 66 | //glFinish(); | ||
3117 | 67 | //t3 = timer.restart(); | ||
3118 | 68 | //qDebug() << "GLVSyncTestWidget "<< t1 << t2 << t3; | ||
3119 | 69 | return t1/1000; // return timer for painter setup | ||
3120 | 55 | } | 70 | } |
3121 | 56 | 71 | ||
3122 | 57 | void QtWaveformWidget::postRender() { | 72 | void QtWaveformWidget::postRender() { |
3123 | 58 | 73 | ||
3124 | === modified file 'mixxx/src/waveform/widgets/qtwaveformwidget.h' | |||
3125 | --- mixxx/src/waveform/widgets/qtwaveformwidget.h 2012-09-19 21:39:13 +0000 | |||
3126 | +++ mixxx/src/waveform/widgets/qtwaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
3127 | @@ -11,19 +11,20 @@ | |||
3128 | 11 | QtWaveformWidget(const char* group, QWidget* parent); | 11 | QtWaveformWidget(const char* group, QWidget* parent); |
3129 | 12 | virtual ~QtWaveformWidget(); | 12 | virtual ~QtWaveformWidget(); |
3130 | 13 | 13 | ||
3132 | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::QtWaveform;} | 14 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::QtWaveform; } |
3133 | 15 | 15 | ||
3137 | 16 | static inline QString getWaveformWidgetName() { return tr("Filtered") + " - Qt";} | 16 | static inline QString getWaveformWidgetName() { return tr("Filtered") + " - Qt"; } |
3138 | 17 | static inline bool useOpenGl() { return true;} | 17 | static inline bool useOpenGl() { return true; } |
3139 | 18 | static inline bool useOpenGLShaders() { return false;} | 18 | static inline bool useOpenGLShaders() { return false; } |
3140 | 19 | static inline bool developerOnly() { return false; } | ||
3141 | 19 | 20 | ||
3142 | 20 | protected: | 21 | protected: |
3143 | 21 | virtual void castToQWidget(); | 22 | virtual void castToQWidget(); |
3144 | 22 | virtual void paintEvent(QPaintEvent* event); | 23 | virtual void paintEvent(QPaintEvent* event); |
3145 | 23 | virtual void postRender(); | 24 | virtual void postRender(); |
3146 | 25 | virtual int render(); | ||
3147 | 24 | 26 | ||
3148 | 25 | private: | 27 | private: |
3149 | 26 | QtWaveformWidget() {} | ||
3150 | 27 | friend class WaveformWidgetFactory; | 28 | friend class WaveformWidgetFactory; |
3151 | 28 | }; | 29 | }; |
3152 | 29 | 30 | ||
3153 | 30 | 31 | ||
3154 | === modified file 'mixxx/src/waveform/widgets/softwarewaveformwidget.h' | |||
3155 | --- mixxx/src/waveform/widgets/softwarewaveformwidget.h 2012-11-04 20:33:22 +0000 | |||
3156 | +++ mixxx/src/waveform/widgets/softwarewaveformwidget.h 2013-05-01 22:08:27 +0000 | |||
3157 | @@ -10,18 +10,18 @@ | |||
3158 | 10 | public: | 10 | public: |
3159 | 11 | virtual ~SoftwareWaveformWidget(); | 11 | virtual ~SoftwareWaveformWidget(); |
3160 | 12 | 12 | ||
3162 | 13 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::SoftwareWaveform;} | 13 | virtual WaveformWidgetType::Type getType() const { return WaveformWidgetType::SoftwareWaveform; } |
3163 | 14 | 14 | ||
3167 | 15 | static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("Software");} | 15 | static inline QString getWaveformWidgetName() { return tr("Filtered") + " - " + tr("Software"); } |
3168 | 16 | static inline bool useOpenGl() { return false;} | 16 | static inline bool useOpenGl() { return false; } |
3169 | 17 | static inline bool useOpenGLShaders() { return false;} | 17 | static inline bool useOpenGLShaders() { return false; } |
3170 | 18 | static inline bool developerOnly() { return false; } | ||
3171 | 18 | 19 | ||
3172 | 19 | protected: | 20 | protected: |
3173 | 20 | virtual void castToQWidget(); | 21 | virtual void castToQWidget(); |
3174 | 21 | virtual void paintEvent(QPaintEvent* event); | 22 | virtual void paintEvent(QPaintEvent* event); |
3175 | 22 | 23 | ||
3176 | 23 | private: | 24 | private: |
3177 | 24 | SoftwareWaveformWidget() {} | ||
3178 | 25 | SoftwareWaveformWidget(const char* group, QWidget* parent); | 25 | SoftwareWaveformWidget(const char* group, QWidget* parent); |
3179 | 26 | friend class WaveformWidgetFactory; | 26 | friend class WaveformWidgetFactory; |
3180 | 27 | }; | 27 | }; |
3181 | 28 | 28 | ||
3182 | === modified file 'mixxx/src/waveform/widgets/waveformwidgetabstract.cpp' | |||
3183 | --- mixxx/src/waveform/widgets/waveformwidgetabstract.cpp 2012-12-10 17:23:43 +0000 | |||
3184 | +++ mixxx/src/waveform/widgets/waveformwidgetabstract.cpp 2013-05-01 22:08:27 +0000 | |||
3185 | @@ -4,15 +4,10 @@ | |||
3186 | 4 | #include <QtDebug> | 4 | #include <QtDebug> |
3187 | 5 | #include <QWidget> | 5 | #include <QWidget> |
3188 | 6 | 6 | ||
3189 | 7 | // Default constructor is only use by the factory to evaluate dynamically | ||
3190 | 8 | // WaveformWidget | ||
3191 | 9 | WaveformWidgetAbstract::WaveformWidgetAbstract() : | ||
3192 | 10 | WaveformWidgetRenderer() { | ||
3193 | 11 | m_widget = NULL; | ||
3194 | 12 | } | ||
3195 | 13 | 7 | ||
3198 | 14 | WaveformWidgetAbstract::WaveformWidgetAbstract( const char* group) : | 8 | WaveformWidgetAbstract::WaveformWidgetAbstract( const char* group) |
3199 | 15 | WaveformWidgetRenderer(group) { | 9 | : WaveformWidgetRenderer(group), |
3200 | 10 | m_initSuccess(false) { | ||
3201 | 16 | m_widget = NULL; | 11 | m_widget = NULL; |
3202 | 17 | } | 12 | } |
3203 | 18 | 13 | ||
3204 | @@ -31,17 +26,15 @@ | |||
3205 | 31 | } | 26 | } |
3206 | 32 | } | 27 | } |
3207 | 33 | 28 | ||
3210 | 34 | void WaveformWidgetAbstract::preRender() { | 29 | void WaveformWidgetAbstract::preRender(VSyncThread* vsyncThread) { |
3211 | 35 | WaveformWidgetRenderer::onPreRender(); | 30 | WaveformWidgetRenderer::onPreRender(vsyncThread); |
3212 | 36 | } | 31 | } |
3213 | 37 | 32 | ||
3215 | 38 | void WaveformWidgetAbstract::render() { | 33 | int WaveformWidgetAbstract::render() { |
3216 | 39 | if (m_widget) { | 34 | if (m_widget) { |
3221 | 40 | if (!m_widget->isVisible()) { | 35 | m_widget->repaint(); // Repaints the widget directly by calling paintEvent() |
3218 | 41 | m_widget->show(); | ||
3219 | 42 | } | ||
3220 | 43 | m_widget->repaint(); | ||
3222 | 44 | } | 36 | } |
3223 | 37 | return 0; // Time for Painter setup, unknown in this case | ||
3224 | 45 | } | 38 | } |
3225 | 46 | 39 | ||
3226 | 47 | void WaveformWidgetAbstract::resize( int width, int height) { | 40 | void WaveformWidgetAbstract::resize( int width, int height) { |
3227 | 48 | 41 | ||
3228 | === modified file 'mixxx/src/waveform/widgets/waveformwidgetabstract.h' | |||
3229 | --- mixxx/src/waveform/widgets/waveformwidgetabstract.h 2012-09-19 21:04:53 +0000 | |||
3230 | +++ mixxx/src/waveform/widgets/waveformwidgetabstract.h 2013-05-01 22:08:27 +0000 | |||
3231 | @@ -8,6 +8,8 @@ | |||
3232 | 8 | #include "waveformwidgettype.h" | 8 | #include "waveformwidgettype.h" |
3233 | 9 | #include "trackinfoobject.h" | 9 | #include "trackinfoobject.h" |
3234 | 10 | 10 | ||
3235 | 11 | class VSyncThread; | ||
3236 | 12 | |||
3237 | 11 | // NOTE(vRince) This class represent objects the waveformwidgetfactory can | 13 | // NOTE(vRince) This class represent objects the waveformwidgetfactory can |
3238 | 12 | // holds, IMPORTANT all WaveformWidgetAbstract MUST inherist QWidget too !! we | 14 | // holds, IMPORTANT all WaveformWidgetAbstract MUST inherist QWidget too !! we |
3239 | 13 | // can't do it here because QWidget and QGLWidget are both QWidgets so they | 15 | // can't do it here because QWidget and QGLWidget are both QWidgets so they |
3240 | @@ -27,9 +29,9 @@ | |||
3241 | 27 | void hold(); | 29 | void hold(); |
3242 | 28 | void release(); | 30 | void release(); |
3243 | 29 | 31 | ||
3247 | 30 | virtual void preRender(); | 32 | virtual void preRender(VSyncThread* vsyncThread); |
3248 | 31 | virtual void render(); | 33 | virtual int render(); |
3249 | 32 | virtual void postRender() {} | 34 | virtual void postRender() {}; |
3250 | 33 | 35 | ||
3251 | 34 | virtual void resize( int width, int height); | 36 | virtual void resize( int width, int height); |
3252 | 35 | 37 | ||
3253 | @@ -37,7 +39,6 @@ | |||
3254 | 37 | QWidget* m_widget; | 39 | QWidget* m_widget; |
3255 | 38 | bool m_initSuccess; | 40 | bool m_initSuccess; |
3256 | 39 | 41 | ||
3257 | 40 | WaveformWidgetAbstract(); | ||
3258 | 41 | //this is the factory resposability to trigger QWidget casting after constructor | 42 | //this is the factory resposability to trigger QWidget casting after constructor |
3259 | 42 | virtual void castToQWidget() = 0; | 43 | virtual void castToQWidget() = 0; |
3260 | 43 | 44 | ||
3261 | 44 | 45 | ||
3262 | === modified file 'mixxx/src/waveform/widgets/waveformwidgettype.h' | |||
3263 | --- mixxx/src/waveform/widgets/waveformwidgettype.h 2012-12-13 22:46:16 +0000 | |||
3264 | +++ mixxx/src/waveform/widgets/waveformwidgettype.h 2013-05-01 22:08:27 +0000 | |||
3265 | @@ -6,13 +6,14 @@ | |||
3266 | 6 | enum Type { | 6 | enum Type { |
3267 | 7 | EmptyWaveform = 0, | 7 | EmptyWaveform = 0, |
3268 | 8 | SoftwareSimpleWaveform, //TODO | 8 | SoftwareSimpleWaveform, //TODO |
3271 | 9 | SoftwareWaveform, //TODO | 9 | SoftwareWaveform, |
3272 | 10 | QtSimpleWaveform, //TODO | 10 | QtSimpleWaveform, |
3273 | 11 | QtWaveform, | 11 | QtWaveform, |
3274 | 12 | GLSimpleWaveform, | 12 | GLSimpleWaveform, |
3275 | 13 | GLWaveform, | 13 | GLWaveform, |
3276 | 14 | GLSLWaveform, | 14 | GLSLWaveform, |
3277 | 15 | HSVWaveform, | 15 | HSVWaveform, |
3278 | 16 | GLVSyncTest, | ||
3279 | 16 | Count_WaveformwidgetType // Also used as invalid value | 17 | Count_WaveformwidgetType // Also used as invalid value |
3280 | 17 | }; | 18 | }; |
3281 | 18 | }; | 19 | }; |
3282 | 19 | 20 | ||
3283 | === modified file 'mixxx/src/widget/wspinny.cpp' | |||
3284 | --- mixxx/src/widget/wspinny.cpp 2013-04-05 23:13:45 +0000 | |||
3285 | +++ mixxx/src/widget/wspinny.cpp 2013-05-01 22:08:27 +0000 | |||
3286 | @@ -7,6 +7,7 @@ | |||
3287 | 7 | #include "controlobject.h" | 7 | #include "controlobject.h" |
3288 | 8 | #include "controlobjectthreadmain.h" | 8 | #include "controlobjectthreadmain.h" |
3289 | 9 | #include "sharedglcontext.h" | 9 | #include "sharedglcontext.h" |
3290 | 10 | #include "visualplayposition.h" | ||
3291 | 10 | #include "wspinny.h" | 11 | #include "wspinny.h" |
3292 | 11 | 12 | ||
3293 | 12 | WSpinny::WSpinny(QWidget* parent, VinylControlManager* pVCMan) | 13 | WSpinny::WSpinny(QWidget* parent, VinylControlManager* pVCMan) |
3294 | @@ -16,7 +17,6 @@ | |||
3295 | 16 | m_pGhostImage(NULL), | 17 | m_pGhostImage(NULL), |
3296 | 17 | m_pPlay(NULL), | 18 | m_pPlay(NULL), |
3297 | 18 | m_pPlayPos(NULL), | 19 | m_pPlayPos(NULL), |
3298 | 19 | m_pVisualPlayPos(NULL), | ||
3299 | 20 | m_pDuration(NULL), | 20 | m_pDuration(NULL), |
3300 | 21 | m_pTrackSamples(NULL), | 21 | m_pTrackSamples(NULL), |
3301 | 22 | m_pScratch(NULL), | 22 | m_pScratch(NULL), |
3302 | @@ -50,7 +50,7 @@ | |||
3303 | 50 | 50 | ||
3304 | 51 | WSpinny::~WSpinny() { | 51 | WSpinny::~WSpinny() { |
3305 | 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. |
3307 | 53 | if (!m_group.isEmpty()) { | 53 | if (!m_group.isEmpty()) { |
3308 | 54 | WImageStore::deleteImage(m_pBgImage); | 54 | WImageStore::deleteImage(m_pBgImage); |
3309 | 55 | WImageStore::deleteImage(m_pFgImage); | 55 | WImageStore::deleteImage(m_pFgImage); |
3310 | 56 | WImageStore::deleteImage(m_pGhostImage); | 56 | WImageStore::deleteImage(m_pGhostImage); |
3311 | @@ -96,8 +96,8 @@ | |||
3312 | 96 | ConfigKey(group, "play"))); | 96 | ConfigKey(group, "play"))); |
3313 | 97 | m_pPlayPos = new ControlObjectThreadMain(ControlObject::getControl( | 97 | m_pPlayPos = new ControlObjectThreadMain(ControlObject::getControl( |
3314 | 98 | ConfigKey(group, "playposition"))); | 98 | ConfigKey(group, "playposition"))); |
3317 | 99 | m_pVisualPlayPos = new ControlObjectThreadMain(ControlObject::getControl( | 99 | m_pVisualPlayPos = VisualPlayPosition::getVisualPlayPosition(group); |
3318 | 100 | ConfigKey(group, "visual_playposition"))); | 100 | |
3319 | 101 | m_pDuration = new ControlObjectThreadMain(ControlObject::getControl( | 101 | m_pDuration = new ControlObjectThreadMain(ControlObject::getControl( |
3320 | 102 | ConfigKey(group, "duration"))); | 102 | ConfigKey(group, "duration"))); |
3321 | 103 | m_pTrackSamples = new ControlObjectThreadMain(ControlObject::getControl( | 103 | m_pTrackSamples = new ControlObjectThreadMain(ControlObject::getControl( |
3322 | @@ -115,8 +115,6 @@ | |||
3323 | 115 | 115 | ||
3324 | 116 | m_pSlipEnabled = new ControlObjectThreadMain(ControlObject::getControl( | 116 | m_pSlipEnabled = new ControlObjectThreadMain(ControlObject::getControl( |
3325 | 117 | ConfigKey(group, "slip_enabled"))); | 117 | ConfigKey(group, "slip_enabled"))); |
3326 | 118 | m_pSlipPosition = new ControlObjectThreadMain(ControlObject::getControl( | ||
3327 | 119 | ConfigKey(group, "slip_playposition"))); | ||
3328 | 120 | 118 | ||
3329 | 121 | #ifdef __VINYLCONTROL__ | 119 | #ifdef __VINYLCONTROL__ |
3330 | 122 | m_pVinylControlSpeedType = new ControlObjectThreadMain(ControlObject::getControl( | 120 | m_pVinylControlSpeedType = new ControlObjectThreadMain(ControlObject::getControl( |
3331 | @@ -211,8 +209,9 @@ | |||
3332 | 211 | p.save(); | 209 | p.save(); |
3333 | 212 | } | 210 | } |
3334 | 213 | 211 | ||
3337 | 214 | double playPosition = m_pVisualPlayPos->get(); | 212 | double playPosition = -1; |
3338 | 215 | double slipPosition = m_pSlipPosition->get(); | 213 | double slipPosition = -1; |
3339 | 214 | m_pVisualPlayPos->getPlaySlipAt(0, &playPosition, &slipPosition); | ||
3340 | 216 | 215 | ||
3341 | 217 | if (playPosition != m_dAngleLastPlaypos) { | 216 | if (playPosition != m_dAngleLastPlaypos) { |
3342 | 218 | m_fAngle = calculateAngle(playPosition); | 217 | m_fAngle = calculateAngle(playPosition); |
3343 | 219 | 218 | ||
3344 | === modified file 'mixxx/src/widget/wspinny.h' | |||
3345 | --- mixxx/src/widget/wspinny.h 2013-03-23 12:47:24 +0000 | |||
3346 | +++ mixxx/src/widget/wspinny.h 2013-05-01 22:08:27 +0000 | |||
3347 | @@ -11,6 +11,7 @@ | |||
3348 | 11 | #endif | 11 | #endif |
3349 | 12 | 12 | ||
3350 | 13 | class ControlObjectThreadMain; | 13 | class ControlObjectThreadMain; |
3351 | 14 | class VisualPlayPosition; | ||
3352 | 14 | 15 | ||
3353 | 15 | class WSpinny : public QGLWidget { | 16 | class WSpinny : public QGLWidget { |
3354 | 16 | Q_OBJECT | 17 | Q_OBJECT |
3355 | @@ -48,7 +49,7 @@ | |||
3356 | 48 | QImage* m_pGhostImage; | 49 | QImage* m_pGhostImage; |
3357 | 49 | ControlObjectThreadMain* m_pPlay; | 50 | ControlObjectThreadMain* m_pPlay; |
3358 | 50 | ControlObjectThreadMain* m_pPlayPos; | 51 | ControlObjectThreadMain* m_pPlayPos; |
3360 | 51 | ControlObjectThreadMain* m_pVisualPlayPos; | 52 | VisualPlayPosition* m_pVisualPlayPos; |
3361 | 52 | ControlObjectThreadMain* m_pDuration; | 53 | ControlObjectThreadMain* m_pDuration; |
3362 | 53 | ControlObjectThreadMain* m_pTrackSamples; | 54 | ControlObjectThreadMain* m_pTrackSamples; |
3363 | 54 | ControlObjectThreadMain* m_pTrackSampleRate; | 55 | ControlObjectThreadMain* m_pTrackSampleRate; |
3364 | @@ -60,7 +61,6 @@ | |||
3365 | 60 | ControlObjectThreadMain* m_pVinylControlEnabled; | 61 | ControlObjectThreadMain* m_pVinylControlEnabled; |
3366 | 61 | ControlObjectThreadMain* m_pSignalEnabled; | 62 | ControlObjectThreadMain* m_pSignalEnabled; |
3367 | 62 | ControlObjectThreadMain* m_pSlipEnabled; | 63 | ControlObjectThreadMain* m_pSlipEnabled; |
3368 | 63 | ControlObjectThreadMain* m_pSlipPosition; | ||
3369 | 64 | 64 | ||
3370 | 65 | #ifdef __VINYLCONTROL__ | 65 | #ifdef __VINYLCONTROL__ |
3371 | 66 | VinylControlManager* m_pVCManager; | 66 | VinylControlManager* m_pVCManager; |
FYI branch needs the diff from https:/ /bazaar. launchpad. net/~mixxxdevel opers/mixxx/ release- 1.11.x/ revision/ 3836 in order to compile on OSX. Going to test branch on MacBookPro8,1 and iMac13,1