| @@ -41,7 +41,7 @@ Audio_File_SF::from_file ( const char *filename ) | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if ( si.samplerate != timeline->sample_rate ) | |||||
| if ( si.samplerate != timeline->sample_rate() ) | |||||
| { | { | ||||
| printf( "error: samplerate mismatch!\n" ); | printf( "error: samplerate mismatch!\n" ); | ||||
| goto invalid; | goto invalid; | ||||
| @@ -43,13 +43,15 @@ Peaks::peakbuffer Peaks::peakbuf; | |||||
| /** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be | /** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be | ||||
| * called before any calls to operator[] */ | * called before any calls to operator[] */ | ||||
| void | void | ||||
| Peaks::fill_buffer ( int s, int e ) const | |||||
| Peaks::fill_buffer ( float fpp, int s, int e ) const | |||||
| { | { | ||||
| if ( timeline->fpp < _peaks->chunksize ) | |||||
| _fpp = fpp; | |||||
| if ( fpp < _peaks->chunksize ) | |||||
| { | { | ||||
| /* looks like we're going to have to switch to a higher resolution peak file | /* looks like we're going to have to switch to a higher resolution peak file | ||||
| or read directly from the source */ | or read directly from the source */ | ||||
| read_peaks( s, e, (e - s) / timeline->fpp, timeline->fpp ); | |||||
| read_peaks( s, e, (e - s) / fpp, fpp ); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -144,9 +146,9 @@ Peaks::peak ( nframes_t start, nframes_t end ) const | |||||
| /* Is there a better way to return this? */ | /* Is there a better way to return this? */ | ||||
| static Peak p; | static Peak p; | ||||
| if ( timeline->fpp < _peaks->chunksize ) | |||||
| if ( _fpp < _peaks->chunksize ) | |||||
| { | { | ||||
| assert( timeline->fpp == peakbuf.buf->chunksize ); | |||||
| assert( _fpp == peakbuf.buf->chunksize ); | |||||
| start = (start - peakbuf.offset) / peakbuf.buf->chunksize; | start = (start - peakbuf.offset) / peakbuf.buf->chunksize; | ||||
| end = (end - peakbuf.offset) / peakbuf.buf->chunksize; | end = (end - peakbuf.offset) / peakbuf.buf->chunksize; | ||||
| @@ -288,11 +290,11 @@ Peaks::make_peaks ( int chunksize ) | |||||
| /end/ (uses known peak data if possible */ | /end/ (uses known peak data if possible */ | ||||
| float | float | ||||
| Peaks::normalization_factor( nframes_t start, nframes_t end ) const | |||||
| Peaks::normalization_factor( float fpp, nframes_t start, nframes_t end ) const | |||||
| { | { | ||||
| float s; | float s; | ||||
| fill_buffer( start, end ); | |||||
| fill_buffer( fpp, start, end ); | |||||
| Peak p = peak( start, end ); | Peak p = peak( start, end ); | ||||
| @@ -63,6 +63,8 @@ class Peaks | |||||
| size_t _len; | size_t _len; | ||||
| mutable float _fpp; | |||||
| void read_peaks ( int s, int e, int npeaks, int chunksize ) const; | void read_peaks ( int s, int e, int npeaks, int chunksize ) const; | ||||
| int clip_read_peaks ( Peak *peaks, int npeaks, int chunksize ) const; | int clip_read_peaks ( Peak *peaks, int npeaks, int chunksize ) const; | ||||
| @@ -98,12 +100,12 @@ public: | |||||
| void clip ( Audio_File *c ) { _clip = c; } | void clip ( Audio_File *c ) { _clip = c; } | ||||
| void channel ( int v ) { _channel = v; } | void channel ( int v ) { _channel = v; } | ||||
| void fill_buffer ( int s, int e ) const; | |||||
| void fill_buffer ( float fpp, int s, int e ) const; | |||||
| void downsample ( Peak *peaks, int s, int e, float *mhi, float *mlo ) const; | void downsample ( Peak *peaks, int s, int e, float *mhi, float *mlo ) const; | ||||
| void read ( int X, float *hi, float *lo ) const; | void read ( int X, float *hi, float *lo ) const; | ||||
| bool open ( void ); | bool open ( void ); | ||||
| float normalization_factor( nframes_t start, nframes_t end ) const; | |||||
| float normalization_factor( float fpp, nframes_t start, nframes_t end ) const; | |||||
| bool current ( void ) const; | bool current ( void ) const; | ||||
| bool make_peaks ( int chunksize ); | bool make_peaks ( int chunksize ); | ||||
| @@ -465,10 +465,7 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| int ch = (h() - Fl::box_dh( box() )) / _clip->channels(); | int ch = (h() - Fl::box_dh( box() )) / _clip->channels(); | ||||
| for ( int i = _clip->channels(); i--; ) | for ( int i = _clip->channels(); i--; ) | ||||
| // draw_waveform( rx, y() + (i * ch), rw, ch, _clip, i, | |||||
| // _start + offset, min( (_end - _start) - offset, _end), | |||||
| // _scale, _selected ? _color : fl_invert_color( _color ) ); | |||||
| draw_waveform( rx, X, (y() + Fl::box_dy( box() )) + (i * ch), W, ch, _clip, i, | |||||
| draw_waveform( rx, X, (y() + Fl::box_dy( box() )) + (i * ch), W, ch, _clip, i, timeline->fpp(), | |||||
| _start + offset, min( (_end - _start) - offset, _end), | _start + offset, min( (_end - _start) - offset, _end), | ||||
| _scale, selected() ? fl_invert_color( _color ) : _color ); | _scale, selected() ? fl_invert_color( _color ) : _color ); | ||||
| @@ -485,7 +482,7 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| { | { | ||||
| char pat[40]; | char pat[40]; | ||||
| snprintf( pat, sizeof( pat ), "%dm:%.1fs", (int)(length() / timeline->sample_rate) / 60, (double)length() / timeline->sample_rate ); | |||||
| snprintf( pat, sizeof( pat ), "%dm:%.1fs", (int)(length() / timeline->sample_rate()) / 60, (double)length() / timeline->sample_rate() ); | |||||
| draw_label( pat, (Fl_Align)(FL_ALIGN_INSIDE | FL_ALIGN_CENTER), FL_GREEN ); | draw_label( pat, (Fl_Align)(FL_ALIGN_INSIDE | FL_ALIGN_CENTER), FL_GREEN ); | ||||
| } | } | ||||
| @@ -510,7 +507,7 @@ Region::normalize ( void ) | |||||
| printf( "normalize: start=%lu end=%lu\n", _start, _end ); | printf( "normalize: start=%lu end=%lu\n", _start, _end ); | ||||
| /* FIXME: punt */ | /* FIXME: punt */ | ||||
| _scale = _clip->peaks( 0 )->normalization_factor( _start, _end ); | |||||
| _scale = _clip->peaks( 0 )->normalization_factor( timeline->fpp(), _start, _end ); | |||||
| } | } | ||||
| @@ -50,9 +50,9 @@ Timeline::cb_scroll ( Fl_Widget *w ) | |||||
| { | { | ||||
| if ( hscroll->zoom_changed() ) | if ( hscroll->zoom_changed() ) | ||||
| { | { | ||||
| fpp = hscroll->zoom() * 1; | |||||
| _fpp = hscroll->zoom() * 1; | |||||
| int maxx = ts_to_x( length ); | |||||
| int maxx = ts_to_x( _length ); | |||||
| hscroll->range( 0, maxx ); | hscroll->range( 0, maxx ); | ||||
| redraw(); | redraw(); | ||||
| @@ -142,9 +142,9 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi | |||||
| /* Fl_Scroll *o = new Fl_Scroll( 0, 24 * 2, 800, 600 - (24 * 3) ); */ | /* Fl_Scroll *o = new Fl_Scroll( 0, 24 * 2, 800, 600 - (24 * 3) ); */ | ||||
| /* o->type( Fl_Scroll::VERTICAL_ALWAYS ); */ | /* o->type( Fl_Scroll::VERTICAL_ALWAYS ); */ | ||||
| sample_rate = 44100; | |||||
| fpp = 256; | |||||
| length = sample_rate * 60 * 2; | |||||
| _sample_rate = 44100; | |||||
| _fpp = 256; | |||||
| _length = _sample_rate * 60 * 2; | |||||
| { | { | ||||
| Fl_Pack *o = new Fl_Pack( X, rulers->y() + rulers->h(), W - vscroll->w(), 5000 ); | Fl_Pack *o = new Fl_Pack( X, rulers->y() + rulers->h(), W - vscroll->w(), 5000 ); | ||||
| @@ -214,7 +214,7 @@ Timeline::nearest_line ( int ix ) | |||||
| { | { | ||||
| for ( int x = ix - 10; x < ix + 10; ++x ) | for ( int x = ix - 10; x < ix + 10; ++x ) | ||||
| { | { | ||||
| const int measure = ts_to_x( (double)(sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset )); | |||||
| const int measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset )); | |||||
| // const int abs_x = ts_to_x( xoffset ) + x; | // const int abs_x = ts_to_x( xoffset ) + x; | ||||
| @@ -245,7 +245,7 @@ Timeline::draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color ) | |||||
| for ( int x = X; x < X + W; ++x ) | for ( int x = X; x < X + W; ++x ) | ||||
| { | { | ||||
| measure = ts_to_x( (double)(sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset )); | |||||
| measure = ts_to_x( (double)(_sample_rate * 60) / beats_per_minute( x_to_ts( x - Track_Header::width() ) + xoffset )); | |||||
| const int abs_x = ts_to_x( xoffset ) + x - Track_Header::width(); | const int abs_x = ts_to_x( xoffset ) + x - Track_Header::width(); | ||||
| @@ -397,12 +397,19 @@ Timeline::draw_overlay ( void ) | |||||
| const Rectangle &r = _selection; | const Rectangle &r = _selection; | ||||
| fl_color( FL_BLACK ); | fl_color( FL_BLACK ); | ||||
| fl_line_style( FL_SOLID, 2 ); | fl_line_style( FL_SOLID, 2 ); | ||||
| fl_rect( r.x + 2, r.y + 2, r.w, r.h ); | fl_rect( r.x + 2, r.y + 2, r.w, r.h ); | ||||
| fl_color( FL_MAGENTA ); | fl_color( FL_MAGENTA ); | ||||
| fl_line_style( FL_DASH, 2 ); | fl_line_style( FL_DASH, 2 ); | ||||
| fl_rect( r.x, r.y, r.w, r.h ); | fl_rect( r.x, r.y, r.w, r.h ); | ||||
| fl_line( r.x, r.y, r.x + r.w, r.y + r.h ); | |||||
| fl_line( r.x + r.w, r.y, r.x, r.y + r.h ); | |||||
| /* fl_overlay_rect( r.x, r.y, r.w, r.h ); */ | |||||
| fl_line_style( FL_SOLID, 0 ); | fl_line_style( FL_SOLID, 0 ); | ||||
| @@ -91,36 +91,25 @@ class Timeline : public Fl_Overlay_Window | |||||
| static void cb_scroll ( Fl_Widget *w, void *v ); | static void cb_scroll ( Fl_Widget *w, void *v ); | ||||
| void cb_scroll ( Fl_Widget *w ); | void cb_scroll ( Fl_Widget *w ); | ||||
| public: | |||||
| float _fpp; /* frames per pixel */ | |||||
| nframes_t _sample_rate; | |||||
| nframes_t _length; | |||||
| float fpp; /* frames per pixel */ | |||||
| // nframes_t fpp; | |||||
| public: | |||||
| nframes_t sample_rate; | |||||
| nframes_t xoffset; | nframes_t xoffset; | ||||
| nframes_t length; | |||||
| int yposition; | int yposition; | ||||
| Timeline ( int X, int Y, int W, int H, const char *L=0 ); | Timeline ( int X, int Y, int W, int H, const char *L=0 ); | ||||
| int | |||||
| ts_to_x( nframes_t ts ) | |||||
| { | |||||
| // assert( ts / fpp > 0 ); | |||||
| return ts / fpp; | |||||
| } | |||||
| nframes_t | |||||
| x_to_ts ( int x ) | |||||
| { | |||||
| return x * fpp; | |||||
| } | |||||
| /* #define FOR_CHILDREN_OF( name, ind ) \ */ | |||||
| /* for ( int i = (name) ->children(); i-- && ( (ind) = (name) ->child( i ) ); ) */ | |||||
| float fpp ( void ) const { return _fpp; } | |||||
| nframes_t length ( void ) const { return _length; } | |||||
| nframes_t sample_rate ( void ) const { return _sample_rate; } | |||||
| int ts_to_x( nframes_t ts ) const { return ts / _fpp; } | |||||
| nframes_t x_to_ts ( int x ) const { return x * _fpp; } | |||||
| float beats_per_minute ( nframes_t when ) const; | float beats_per_minute ( nframes_t when ) const; | ||||
| int beats_per_bar ( nframes_t when ) const; | int beats_per_bar ( nframes_t when ) const; | ||||
| @@ -31,7 +31,7 @@ | |||||
| /** draw a portion of /clip/'s waveform. coordinates are the portion to draw */ | /** draw a portion of /clip/'s waveform. coordinates are the portion to draw */ | ||||
| void | void | ||||
| draw_waveform ( int ox, int X, int Y, int W, int H, Audio_File *_clip, int channel, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ) | |||||
| draw_waveform ( int ox, int X, int Y, int W, int H, Audio_File *_clip, int channel, float fpp, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ) | |||||
| { | { | ||||
| fl_push_clip( X, Y, W, H ); | fl_push_clip( X, Y, W, H ); | ||||
| @@ -44,7 +44,7 @@ draw_waveform ( int ox, int X, int Y, int W, int H, Audio_File *_clip, int chann | |||||
| _start = timeline->x_to_ts( start ); | _start = timeline->x_to_ts( start ); | ||||
| pk->fill_buffer( _start, _start + timeline->x_to_ts( W ) ); | |||||
| pk->fill_buffer( fpp, _start, _start + timeline->x_to_ts( W ) ); | |||||
| j = start; | j = start; | ||||
| for ( int x = X; x <= X + W; ++x, ++j ) | for ( int x = X; x <= X + W; ++x, ++j ) | ||||
| @@ -26,4 +26,4 @@ | |||||
| #include "Audio_File.H" | #include "Audio_File.H" | ||||
| void draw_waveform ( int rx, int X, int Y, int W, int H, Audio_File *_clip, int channel, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ); | |||||
| void draw_waveform ( int rx, int X, int Y, int W, int H, Audio_File *_clip, int channel, float fpp, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ); | |||||