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"
30 #include <QVBoxLayout>
37 class SoundCacheStream
;
40 SoundCache() : min(0), max(0), sum(0), sum2(0) {};
53 class QcWaveform
: public QWidget
, public QcHelper
{
57 Q_PROPERTY( float readProgress READ loadProgress
);
58 Q_PROPERTY( int startFrame READ startFrame
);
59 Q_PROPERTY( int frames READ frames
);
60 Q_PROPERTY( double viewFrames READ viewFrames
);
61 Q_PROPERTY( double viewStartFrame READ viewStartFrame WRITE scrollTo
);
62 Q_PROPERTY( float scrollPos READ scrollPos WRITE setScrollPos
);
63 Q_PROPERTY( int currentSelection READ currentSelection WRITE setCurrentSelection
);
64 Q_PROPERTY( VariantList selections READ selections
);
66 Q_PROPERTY( float yZoom READ yZoom WRITE setYZoom
);
67 Q_PROPERTY( float xZoom READ xZoom WRITE setXZoom
);
68 Q_PROPERTY( bool cursorVisible READ cursorVisible WRITE setCursorVisible
);
69 Q_PROPERTY( bool cursorEditable READ cursorEditable WRITE setCursorEditable
);
70 Q_PROPERTY( int cursorPosition READ cursorPosition WRITE setCursorPosition
);
71 Q_PROPERTY( bool gridVisible READ gridVisible WRITE setGridVisible
);
72 Q_PROPERTY( float gridOffset READ gridOffset WRITE setGridOffset
);
73 Q_PROPERTY( float gridResolution READ gridResolution WRITE setGridResolution
);
74 Q_PROPERTY( bool drawsWaveform READ drawsWaveform WRITE setDrawsWaveform
);
75 Q_PROPERTY( QColor background READ background WRITE setBackground
);
76 Q_PROPERTY( QColor peakColor READ peakColor WRITE setPeakColor
);
77 Q_PROPERTY( QColor rmsColor READ rmsColor WRITE setRmsColor
);
78 Q_PROPERTY( QColor cursorColor READ cursorColor WRITE setCursorColor
);
79 Q_PROPERTY( QColor gridColor READ gridColor WRITE setGridColor
);
82 Q_INVOKABLE
void load( const QString
& filename
);
84 // NOTE: Using int instead of sf_count_t for accessibility from SC language.
85 Q_INVOKABLE
void load( const QString
& filename
, int beginning
, int duration
);
87 Q_INVOKABLE
void load( const QVector
<double> & data
, int offset
= 0,
88 int channels
= 1, int samplerate
= 44100 );
90 Q_INVOKABLE
void allocate ( int frames
, int channels
= 1, int samplerate
= 44100 );
92 Q_INVOKABLE
void write( const QVector
<double> & data
, int offset
);
97 Selection() : start(0), size(0), editable(true), color(QColor(0,0,150)) {}
104 QcWaveform( QWidget
* parent
= 0 );
107 float loadProgress();
108 sf_count_t
startFrame() { return _rangeBeg
; }
109 sf_count_t
frames() { return _rangeDur
; }
111 double viewStartFrame() { return _beg
; }
112 double viewFrames() { return _dur
; }
113 float scrollPos(); // as fraction of scrolling range
114 float zoom(); //visible fraction
115 float xZoom(); //visible seconds
116 float yZoom(); //factor
118 VariantList
selections() const;
119 int currentSelection() const { return _curSel
; }
120 void setCurrentSelection( int i
);
121 // for SC: selection start relative to first loaded frame
122 Q_INVOKABLE VariantList
selection( int index
) const;
123 // for SC: selection start relative to first loaded frame
124 Q_INVOKABLE
void setSelection( int index
, VariantList data
);
125 void setSelection( int i
, sf_count_t a
, sf_count_t b
);
126 Q_INVOKABLE
void setSelectionStart( int i
, sf_count_t frame
);
127 Q_INVOKABLE
void setSelectionEnd( int i
, sf_count_t frame
);
128 Q_INVOKABLE
void setSelectionEditable( int index
, bool editable
);
129 Q_INVOKABLE
void setSelectionColor( int index
, const QColor
&clr
);
130 Q_PROPERTY( VariantList waveColors READ waveColors WRITE setWaveColors
);
132 bool cursorVisible() const { return _showCursor
; }
133 void setCursorVisible( bool b
) { _showCursor
= b
; update(); }
134 int cursorPosition() const { return _cursorPos
; }
135 void setCursorPosition( int pos
) { _cursorPos
= pos
; update(); }
136 bool cursorEditable() const { return _cursorEditable
; }
137 void setCursorEditable( bool b
) { _cursorEditable
= b
; }
139 bool gridVisible() const { return _showGrid
; }
140 void setGridVisible( bool b
) { _showGrid
= b
; update(); }
141 float gridOffset() const { return _gridOffset
; }
142 void setGridOffset( float f
) { _gridOffset
= f
; update(); }
143 float gridResolution() const { return _gridResolution
; }
144 void setGridResolution( float f
) { _gridResolution
= f
; update(); }
146 bool drawsWaveform() const { return _drawWaveform
; }
147 void setDrawsWaveform( bool b
) { _drawWaveform
= b
; update(); }
148 VariantList
waveColors() const;
149 void setWaveColors( const VariantList
& );
151 const QColor
& background() const { return _bkgColor
; }
152 void setBackground( const QColor
&c
)
154 if(_bkgColor
== c
) return;
156 setAttribute(Qt::WA_OpaquePaintEvent
, c
.isValid() && c
.alpha() == 255);
159 const QColor
& peakColor() const { return _peakColor
; }
160 void setPeakColor( const QColor
&clr
) { _peakColor
= clr
; redraw(); }
161 const QColor
& rmsColor() const { return _rmsColor
; }
162 void setRmsColor( const QColor
&clr
) { _rmsColor
= clr
; redraw(); }
163 const QColor
& cursorColor() const { return _cursorColor
; }
164 void setCursorColor( const QColor
&c
) { _cursorColor
= c
; update(); }
165 const QColor
& gridColor() const { return _gridColor
; }
166 void setGridColor( const QColor
&c
) { _gridColor
= c
; update(); }
168 QSize
sizeHint() const { return QSize( 400, 200 ); }
169 QSize
minimumSizeHint() const { return QSize( 100, 20 ); }
172 void zoomTo( double fraction
);
173 //void zoomTo( float fraction, quint64 frame );
174 void zoomBy( double factor
);
176 void zoomSelection( int selectionIndex
);
177 void scrollTo( double frame
);
178 void scrollBy( double frames
);
179 void setScrollPos( double fraction
); // as fraction of scrolling range
180 void scrollToStart();
182 void setYZoom( double factor
);
183 void setXZoom( double seconds
);
188 void loadProgress( int );
203 virtual void resizeEvent( QResizeEvent
* );
204 virtual void paintEvent( QPaintEvent
* );
205 virtual void keyPressEvent( QKeyEvent
* );
206 virtual void mousePressEvent( QMouseEvent
* );
207 virtual void mouseDoubleClickEvent ( QMouseEvent
* );
208 virtual void mouseMoveEvent( QMouseEvent
* );
212 void doLoad( SNDFILE
*new_sf
, const SF_INFO
&new_info
, sf_count_t beginning
, sf_count_t duration
);
213 inline void updateFPP() { _fpp
= width() ? (double) _dur
/ width() : 0.0; }
214 void rebuildCache ( int maxFramesPerCache
, int maxRawFrames
);
215 void draw ( QPixmap
*, int x
, int width
, double beginning
, double duration
);
220 sf_count_t _rangeBeg
;
221 sf_count_t _rangeDur
;
222 sf_count_t _rangeEnd
;
224 SoundCacheStream
*_cache
;
227 Selection _selections
[64];
232 sf_count_t _cursorPos
;
233 bool _cursorEditable
;
237 float _gridResolution
;
255 QList
<QColor
> _waveColors
;
265 DragAction _dragAction
;
267 sf_count_t _dragFrame
;
274 inline int channels() { return _ch
; }
276 inline sf_count_t
beginning() { return _beg
; }
278 inline sf_count_t
duration() { return _dur
; }
280 virtual bool displayData( int channel
, double offset
, double duration
,
285 int bufferSize
) = 0;
287 virtual short *rawFrames( int channel
, sf_count_t beginning
, sf_count_t duration
, bool *interleaved
) = 0;
291 : _ch( 0 ), _beg( 0 ), _dur( 0 ) {}
293 SoundStream( int channels
, sf_count_t beginning
, sf_count_t duration
) :
294 _ch( channels
), _beg( beginning
), _dur( duration
) {}
301 class SoundFileStream
: public SoundStream
305 SoundFileStream( SNDFILE
*sf
, const SF_INFO
&sf_info
, sf_count_t beginning
, sf_count_t duration
);
307 void load( SNDFILE
*sf
, const SF_INFO
&sf_info
, sf_count_t beginning
, sf_count_t duration
);
308 bool integrate( int channel
, double offset
, double duration
,
314 bool displayData( int channel
, double offset
, double duration
,
320 short *rawFrames( int channel
, sf_count_t beginning
, sf_count_t duration
, bool *interleaved
);
323 sf_count_t _dataSize
;
324 sf_count_t _dataOffset
;
327 class SoundCacheLoader
;
329 class SoundCacheStream
: public QObject
, public SoundStream
331 friend class SoundCacheLoader
;
338 void load( const QVector
<double> & data
, int frames
, int offset
, int channels
);
339 void load( SNDFILE
*sf
, const SF_INFO
&info
, sf_count_t beg
, sf_count_t dur
,
340 int maxFramesPerUnit
, int maxRawFrames
);
341 void allocate ( int frames
, int channels
);
342 void write( const QVector
<double> & data
, int offset
, int count
);
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
,
354 short *rawFrames( int channel
, sf_count_t beginning
, sf_count_t duration
, bool *interleaved
);
357 void loadProgress( int );
361 void onLoadProgress( int );
362 void onLoadingDone();
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
371 SoundCacheLoader
*_loader
;
375 class SoundCacheLoader
: public QThread
379 SoundCacheLoader( SoundCacheStream
*cache
) : QThread( cache
), _cache( cache
), _sf(0) {}
380 void load( SNDFILE
*sf
, const SF_INFO
&info
);
383 void loadProgress( int );
388 SoundCacheStream
*_cache
;