1 /***************************************************************************
2 * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
3 * This file is part of kdenlive. See www.kdenlive.org. *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 ***************************************************************************/
11 #ifndef ABSTRACTAUDIOSCOPEWIDGET_H
12 #define ABSTRACTAUDIOSCOPEWIDGET_H
23 class AbstractAudioScopeWidget : public QWidget
27 AbstractAudioScopeWidget(Monitor *projMonitor, Monitor *clipMonitor, bool trackMouse = false, QWidget *parent = 0);
28 virtual ~AbstractAudioScopeWidget(); // Must be virtual because of inheritance, to avoid memory leaks
29 QPalette m_scopePalette;
31 /** Initializes widget settings (reads configuration).
32 Has to be called in the implementing object. */
35 /** Does this scope have auto-refresh enabled */
36 bool autoRefreshEnabled();
38 ///// Unimplemented /////
40 virtual QString widgetName() const = 0;
43 static const QPen penThick;
44 static const QPen penThin;
45 static const QPen penLight;
46 static const QPen penDark;
51 Monitor *m_projMonitor;
52 Monitor *m_clipMonitor;
53 Render *m_activeRender;
56 /** The context menu. Feel free to add new entries in your implementation. */
59 /** Enables auto refreshing of the scope.
60 This is when a new frame is shown on the active monitor.
61 Resize events always force a recalculation. */
62 QAction *m_aAutoRefresh;
64 /** Realtime rendering. Should be disabled if it is not supported.
65 Use the accelerationFactor variable passed to the render functions as a hint of
66 how many times faster the scope should be calculated. */
69 /** The mouse position; Updated when the mouse enters the widget
70 AND mouse tracking has been enabled. */
72 /** Knows whether the mouse currently lies within the widget or not.
73 Can e.g. be used for drawing a HUD only when the mouse is in the widget. */
74 bool m_mouseWithinWidget;
76 /** Offset from the widget's borders */
79 /** The rect on the widget we're painting in.
80 Can be used by the implementing widget, e.g. in the render methods.
81 Is updated when necessary (size changes). */
84 /** Images storing the calculated layers. Will be used on repaint events. */
87 QImage m_imgBackground;
89 /** The acceleration factors can be accessed also by other renderer tasks,
90 e.g. to display the scope's acceleration factor in the HUD renderer. */
92 int m_accelFactorScope;
93 int m_accelFactorBackground;
95 /** Reads the widget's configuration.
96 Can be extended in the implementing subclass (make sure to run readConfig as well). */
97 virtual void readConfig();
98 /** Writes the widget configuration.
99 Implementing widgets have to implement an own method and run it in their destructor. */
101 /** Identifier for the widget's configuration. */
102 QString configName();
105 ///// Unimplemented Methods /////
107 /** Where on the widget we can paint in.
108 May also update other variables that depend on the widget's size. */
109 virtual QRect scopeRect() = 0;
111 /** @brief HUD renderer. Must emit signalHUDRenderingFinished(). @see renderScope */
112 virtual QImage renderHUD(uint accelerationFactor) = 0;
113 /** @brief Scope renderer. Must emit signalScopeRenderingFinished()
114 when calculation has finished, to allow multi-threading.
115 accelerationFactor hints how much faster than usual the calculation should be accomplished, if possible. */
116 virtual QImage renderScope(uint accelerationFactor,
117 const QVector<int16_t> audioFrame, const int freq, const int num_channels, const int num_samples) = 0;
118 /** @brief Background renderer. Must emit signalBackgroundRenderingFinished(). @see renderScope */
119 virtual QImage renderBackground(uint accelerationFactor) = 0;
121 /** Must return true if the HUD layer depends on the input monitor.
122 If it does not, then it does not need to be re-calculated when
123 a new frame from the monitor is incoming. */
124 virtual bool isHUDDependingOnInput() const = 0;
125 /** @see isHUDDependingOnInput() */
126 virtual bool isScopeDependingOnInput() const = 0;
127 /** @see isHUDDependingOnInput() */
128 virtual bool isBackgroundDependingOnInput() const = 0;
130 ///// Can be reimplemented /////
131 /** Calculates the acceleration factor to be used by the render thread.
132 This method can be refined in the subclass if required. */
133 virtual uint calculateAccelFactorHUD(uint oldMseconds, uint oldFactor);
134 virtual uint calculateAccelFactorScope(uint oldMseconds, uint oldFactor);
135 virtual uint calculateAccelFactorBackground(uint oldMseconds, uint oldFactor);
137 ///// Reimplemented /////
139 void mouseMoveEvent(QMouseEvent *);
140 void leaveEvent(QEvent *);
141 void mouseReleaseEvent(QMouseEvent *);
142 void paintEvent(QPaintEvent *);
143 void resizeEvent(QResizeEvent *);
144 void showEvent(QShowEvent *); // Called when the widget is activated via the Menu entry
145 // void raise(); // Called only when manually calling the event -> useless
149 /** Forces an update of all layers. */
150 void forceUpdate(bool doUpdate = true);
151 void forceUpdateHUD();
152 void forceUpdateScope();
153 void forceUpdateBackground();
154 void slotAutoRefreshToggled(bool);
157 /** mseconds represent the time taken for the calculation,
158 accelerationFactor is the acceleration factor that has been used. */
159 void signalHUDRenderingFinished(uint mseconds, uint accelerationFactor);
160 void signalScopeRenderingFinished(uint mseconds, uint accelerationFactor);
161 void signalBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
163 /** For the mouse position itself see m_mousePos.
164 To check whether the mouse has leaved the widget, see m_mouseWithinWidget. */
165 void signalMousePositionChanged();
167 /** Do we need the renderer to send its frames to us? */
168 void requestAutoRefresh(bool);
172 /** Counts the number of frames that have been rendered in the active monitor.
173 The frame number will be reset when the calculation starts for the current frame. */
174 QAtomicInt m_newHUDFrames;
175 QAtomicInt m_newScopeFrames;
176 QAtomicInt m_newBackgroundFrames;
178 /** Counts the number of updates that, unlike new frames, force a recalculation
179 of the scope, like for example a resize event. */
180 QAtomicInt m_newHUDUpdates;
181 QAtomicInt m_newScopeUpdates;
182 QAtomicInt m_newBackgroundUpdates;
184 /** The semaphores ensure that the QFutures for the HUD/Scope/Background threads cannot
185 be assigned a new thread while it is still running. (Could cause deadlocks and other
186 nasty things known from parallelism.) */
187 QSemaphore m_semaphoreHUD;
188 QSemaphore m_semaphoreScope;
189 QSemaphore m_semaphoreBackground;
191 QFuture<QImage> m_threadHUD;
192 QFuture<QImage> m_threadScope;
193 QFuture<QImage> m_threadBackground;
195 bool initialDimensionUpdateDone;
196 bool m_requestForcedUpdate;
199 QVector<int16_t> m_audioFrame; //NEW
204 QString m_widgetName;
206 void prodHUDThread();
207 void prodScopeThread();
208 void prodBackgroundThread();
211 /** @brief Must be called when the active monitor has shown a new frame.
212 This slot must be connected in the implementing class, it is *not*
213 done in this abstract class. */
214 void slotActiveMonitorChanged(bool isClipMonitor);
217 void customContextMenuRequested(const QPoint &pos);
218 /** To be called when a new frame has been received.
219 The scope then decides whether and when it wants to recalculate the scope, depending
220 on whether it is currently visible and whether a calculation thread is already running. */
221 void slotRenderZoneUpdated();
222 void slotRenderZoneUpdated(QImage);//OLD
223 void slotReceiveAudio(const QVector<int16_t> sampleData, const int freq, const int num_channels, const int num_samples); // NEW, TODO comment
224 /** The following slots are called when rendering of a component has finished. They e.g. update
225 the widget and decide whether to immediately restart the calculation thread. */
226 void slotHUDRenderingFinished(uint mseconds, uint accelerationFactor);
227 void slotScopeRenderingFinished(uint mseconds, uint accelerationFactor);
228 void slotBackgroundRenderingFinished(uint mseconds, uint accelerationFactor);
230 /** Resets the acceleration factors to 1 when realtime rendering is disabled. */
231 void slotResetRealtimeFactor(bool realtimeChecked);
235 #endif // ABSTRACTAUDIOSCOPEWIDGET_H