class library: PriorityQueue - implement removeValue, hide array
[supercollider.git] / QtCollider / widgets / QcSoundFileView.h
blob865bae2a3560b3c0a2bb0e8658f9015837798be5
1 /************************************************************************
3 * Copyright 2010 Jakob Leben (jakob.leben@gmail.com)
5 * This file is part of SuperCollider Qt GUI.
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ************************************************************************/
22 #ifndef QC_SOUND_FILE_VIEW_H
23 #define QC_SOUND_FILE_VIEW_H
25 #include "../Common.h"
26 #include "../QcHelper.h"
28 #include <sndfile.h>
30 #include <QVBoxLayout>
31 #include <QScrollBar>
32 #include <QSlider>
33 #include <QPixmap>
34 #include <QThread>
36 class QcWaveform;
37 class SoundCacheStream;
39 struct SoundCache {
40 SoundCache() : min(0), max(0), sum(0), sum2(0) {};
41 ~SoundCache() {
42 delete [] min;
43 delete [] max;
44 delete [] sum;
45 delete [] sum2;
47 short *min;
48 short *max;
49 float *sum;
50 float *sum2;
53 class QcSoundFileView : public QWidget
55 friend class QcWaveform;
57 Q_OBJECT
60 public:
61 QcSoundFileView();
62 Q_INVOKABLE void load( const QString& filename );
64 private Q_SLOTS:
65 void onPosSliderChanged( int value );
66 void onZoomSliderChanged( int value );
67 private Q_SLOTS:
68 void updateTimeScrollBar();
69 void updateZoomScrollBar();
71 private:
72 QcWaveform *waveform;
73 QVBoxLayout *layout;
74 QScrollBar *timeScrollBar;
75 QSlider *zoomScrollBar;
77 double hScrollMultiplier;
80 class QcWaveform : public QWidget, public QcHelper {
82 Q_OBJECT
84 Q_PROPERTY( float readProgress READ loadProgress );
85 Q_PROPERTY( int startFrame READ startFrame );
86 Q_PROPERTY( int frames READ frames );
87 Q_PROPERTY( double viewFrames READ viewFrames );
88 Q_PROPERTY( double viewStartFrame READ viewStartFrame WRITE scrollTo );
89 Q_PROPERTY( float scrollPos READ scrollPos WRITE setScrollPos );
90 Q_PROPERTY( int currentSelection READ currentSelection WRITE setCurrentSelection );
91 Q_PROPERTY( VariantList selections READ selections );
92 Q_PROPERTY( QColor peakColor READ dummyColor WRITE setPeakColor );
93 Q_PROPERTY( QColor rmsColor READ dummyColor WRITE setRmsColor );
94 Q_PROPERTY( float yZoom READ yZoom WRITE setYZoom );
95 Q_PROPERTY( float xZoom READ xZoom WRITE setXZoom );
96 Q_PROPERTY( bool cursorVisible READ cursorVisible WRITE setCursorVisible );
97 Q_PROPERTY( bool cursorEditable READ cursorEditable WRITE setCursorEditable );
98 Q_PROPERTY( int cursorPosition READ cursorPosition WRITE setCursorPosition );
99 Q_PROPERTY( QColor cursorColor READ cursorColor WRITE setCursorColor );
100 Q_PROPERTY( bool gridVisible READ gridVisible WRITE setGridVisible );
101 Q_PROPERTY( float gridOffset READ gridOffset WRITE setGridOffset );
102 Q_PROPERTY( float gridResolution READ gridResolution WRITE setGridResolution );
103 Q_PROPERTY( QColor gridColor READ gridColor WRITE setGridColor );
104 Q_PROPERTY( bool drawsWaveform READ drawsWaveform WRITE setDrawsWaveform );
106 public:
108 struct Selection {
109 Selection() : start(0), size(0), editable(true), color(QColor(0,0,150)) {}
110 sf_count_t start;
111 sf_count_t size;
112 bool editable;
113 QColor color;
116 QcWaveform( QWidget * parent = 0 );
117 ~QcWaveform();
119 Q_INVOKABLE void load( const QString& filename );
120 // NOTE: Using int instead of sf_count_t for accessibility from SC language.
121 Q_INVOKABLE void load( const QString& filename, int beginning, int duration );
122 float loadProgress();
123 sf_count_t startFrame() { return _rangeBeg; }
124 sf_count_t frames() { return _rangeDur; }
126 double viewStartFrame() { return _beg; }
127 double viewFrames() { return _dur; }
128 float scrollPos(); // as fraction of scrolling range
129 float zoom(); //visible fraction
130 float xZoom(); //visible seconds
131 float yZoom(); //factor
133 VariantList selections() const;
134 int currentSelection() const { return _curSel; }
135 void setCurrentSelection( int i );
136 // for SC: selection start relative to first loaded frame
137 Q_INVOKABLE VariantList selection( int index ) const;
138 // for SC: selection start relative to first loaded frame
139 Q_INVOKABLE void setSelection( int index, VariantList data );
140 void setSelection( int i, sf_count_t a, sf_count_t b );
141 Q_INVOKABLE void setSelectionStart( int i, sf_count_t frame );
142 Q_INVOKABLE void setSelectionEnd( int i, sf_count_t frame );
143 Q_INVOKABLE void setSelectionEditable( int index, bool editable );
144 Q_INVOKABLE void setSelectionColor( int index, const QColor &clr );
145 Q_PROPERTY( VariantList waveColors READ waveColors WRITE setWaveColors );
147 bool cursorVisible() const { return _showCursor; }
148 void setCursorVisible( bool b ) { _showCursor = b; update(); }
149 int cursorPosition() const { return _cursorPos; }
150 void setCursorPosition( int pos ) { _cursorPos = pos; update(); }
151 QColor cursorColor() const { return _cursorColor; }
152 void setCursorColor( const QColor &c ) { _cursorColor = c; update(); }
153 bool cursorEditable() const { return _cursorEditable; }
154 void setCursorEditable( bool b ) { _cursorEditable = b; }
156 bool gridVisible() const { return _showGrid; }
157 void setGridVisible( bool b ) { _showGrid = b; update(); }
158 float gridOffset() const { return _gridOffset; }
159 void setGridOffset( float f ) { _gridOffset = f; update(); }
160 float gridResolution() const { return _gridResolution; }
161 void setGridResolution( float f ) { _gridResolution = f; update(); }
162 QColor gridColor() const { return _gridColor; }
163 void setGridColor( const QColor &c ) { _gridColor = c; update(); }
165 void setPeakColor( const QColor &clr ) { _peakColor = clr; redraw(); }
166 void setRmsColor( const QColor &clr ) { _rmsColor = clr; redraw(); }
168 bool drawsWaveform() const { return _drawWaveform; }
169 void setDrawsWaveform( bool b ) { _drawWaveform = b; update(); }
170 VariantList waveColors() const;
171 void setWaveColors( const VariantList & );
173 QSize sizeHint() const { return QSize( 400, 200 ); }
174 QSize minimumSizeHint() const { return QSize( 100, 20 ); }
176 public Q_SLOTS:
177 void zoomTo( double fraction );
178 //void zoomTo( float fraction, quint64 frame );
179 void zoomBy( double factor );
180 void zoomAllOut();
181 void zoomSelection( int selectionIndex );
182 void scrollTo( double frame );
183 void scrollBy( double frames );
184 void setScrollPos( double fraction ); // as fraction of scrolling range
185 void scrollToStart();
186 void scrollToEnd();
187 void setYZoom( double factor );
188 void setXZoom( double seconds );
191 Q_SIGNALS:
193 void loadProgress( int );
194 void loadingDone();
196 void action();
197 void metaAction();
199 public Q_SLOTS:
201 void redraw() {
202 dirty = true;
203 update();
206 protected:
208 virtual void resizeEvent( QResizeEvent * );
209 virtual void paintEvent( QPaintEvent * );
210 virtual void mousePressEvent( QMouseEvent * );
211 virtual void mouseDoubleClickEvent ( QMouseEvent * );
212 virtual void mouseMoveEvent( QMouseEvent * );
214 private:
216 void doLoad( SNDFILE *new_sf, const SF_INFO &new_info, sf_count_t beginning, sf_count_t duration );
217 inline void updateFPP() { _fpp = width() ? (double) _dur / width() : 0.0; }
218 void rebuildCache ( int maxFramesPerCache, int maxRawFrames );
219 void draw ( QPixmap *, int x, int width, double beginning, double duration );
221 // data
222 SNDFILE *sf;
223 SF_INFO sfInfo;
224 sf_count_t _rangeBeg;
225 sf_count_t _rangeDur;
226 sf_count_t _rangeEnd;
228 SoundCacheStream *_cache;
230 // selections
231 Selection _selections[64];
232 int _curSel;
234 // cursor
235 bool _showCursor;
236 sf_count_t _cursorPos;
237 QColor _cursorColor;
238 bool _cursorEditable;
240 //grid
241 bool _showGrid;
242 float _gridResolution;
243 float _gridOffset;
244 QColor _gridColor;
246 // view
247 double _beg;
248 double _dur;
249 double _fpp;
250 float _yZoom;
252 // painting
253 QPixmap *pixmap;
254 QColor _peakColor;
255 QColor _rmsColor;
256 bool dirty;
257 bool _drawWaveform;
258 QList<QColor> _waveColors;
260 // interaction
261 enum DragAction {
262 NoDragAction,
263 Scroll,
264 Zoom,
265 Select,
266 MoveSelection,
267 MoveCursor
269 DragAction _dragAction;
270 QPointF _dragPoint;
271 sf_count_t _dragFrame;
272 double _dragData;
273 double _dragData2;
276 class SoundStream {
277 public:
278 inline int channels() { return _ch; }
280 inline sf_count_t beginning() { return _beg; }
282 inline sf_count_t duration() { return _dur; }
284 virtual bool displayData( int channel, double offset, double duration,
285 short *minBuffer,
286 short *maxBuffer,
287 short *minRMS,
288 short *maxRMS,
289 int bufferSize ) = 0;
291 virtual short *rawFrames( int channel, sf_count_t beginning, sf_count_t duration, bool *interleaved ) = 0;
293 protected:
294 SoundStream()
295 : _ch( 0 ), _beg( 0 ), _dur( 0 ) {}
297 SoundStream( int channels, sf_count_t beginning, sf_count_t duration ) :
298 _ch( channels ), _beg( beginning ), _dur( duration ) {}
300 int _ch;
301 sf_count_t _beg;
302 sf_count_t _dur;
305 class SoundFileStream : public SoundStream
307 public:
308 SoundFileStream();
309 SoundFileStream( SNDFILE *sf, const SF_INFO &sf_info, sf_count_t beginning, sf_count_t duration );
310 ~SoundFileStream();
311 void load( SNDFILE *sf, const SF_INFO &sf_info, sf_count_t beginning, sf_count_t duration );
312 bool integrate( int channel, double offset, double duration,
313 short *minBuffer,
314 short *maxBuffer,
315 float *sumBuffer,
316 float *sum2Buffer,
317 int bufferSize );
318 bool displayData( int channel, double offset, double duration,
319 short *minBuffer,
320 short *maxBuffer,
321 short *minRMS,
322 short *maxRMS,
323 int bufferSize );
324 short *rawFrames( int channel, sf_count_t beginning, sf_count_t duration, bool *interleaved );
325 private:
326 short *_data;
327 sf_count_t _dataSize;
328 sf_count_t _dataOffset;
331 class SoundCacheLoader;
333 class SoundCacheStream : public QObject, public SoundStream
335 friend class SoundCacheLoader;
337 Q_OBJECT
339 public:
340 SoundCacheStream();
341 ~SoundCacheStream();
342 void load( SNDFILE *sf, const SF_INFO &info, sf_count_t beg, sf_count_t dur,
343 int maxFramesPerUnit, int maxRawFrames );
344 inline double fpu() { return _fpu; }
345 inline bool ready() { return _ready; }
346 inline bool loading() { return _loading; }
347 inline int loadProgress() { return _loadProgress; }
348 bool displayData( int channel, double offset, double duration,
349 short *minBuffer,
350 short *maxBuffer,
351 short *minRMS,
352 short *maxRMS,
353 int bufferSize );
354 short *rawFrames( int channel, sf_count_t beginning, sf_count_t duration, bool *interleaved );
356 Q_SIGNALS:
357 void loadProgress( int );
358 void loadingDone();
360 private Q_SLOTS:
361 void onLoadProgress( int );
362 void onLoadingDone();
364 private:
365 SoundCache *_caches;
366 double _fpu; // soundfile frames per cache unit
367 sf_count_t _dataOffset; // offset into soundfile of first frame cached (in frames)
368 sf_count_t _dataSize; // amount of cache units
369 bool _ready;
370 bool _loading;
371 SoundCacheLoader *_loader;
372 int _loadProgress;
375 class SoundCacheLoader : public QThread
377 Q_OBJECT
378 public:
379 SoundCacheLoader( SoundCacheStream *cache ) : QThread( cache ), _cache( cache ), _sf(0) {}
380 void load( SNDFILE *sf, const SF_INFO &info );
382 Q_SIGNALS:
383 void loadProgress( int );
384 void loadingDone();
385 private:
386 void run();
388 SoundCacheStream *_cache;
389 SNDFILE *_sf;
390 SF_INFO _info;
393 #endif