| @@ -62,6 +62,10 @@ Audio_File::read_peaks( float fpp, nframes_t start, nframes_t end, int *peaks, P | |||||
| { | { | ||||
| Peaks pk; | Peaks pk; | ||||
| *peaks = 0; | |||||
| *channels = 0; | |||||
| *pbuf = NULL; | |||||
| pk.clip( this ); | pk.clip( this ); | ||||
| if ( ! pk.open() ) | if ( ! pk.open() ) | ||||
| @@ -50,10 +50,7 @@ Peaks::fill_buffer ( float fpp, int s, int e ) const | |||||
| { | { | ||||
| _fpp = fpp; | _fpp = fpp; | ||||
| read_peaks( s, e, (e - s) / fpp, fpp ); | |||||
| /* FIXME: are we *SURE* we got them all? */ | |||||
| return (e - s) / fpp; | |||||
| return read_peaks( s, e, (e - s) / fpp, fpp ); | |||||
| } | } | ||||
| @@ -100,6 +97,11 @@ Peaks::read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize | |||||
| int channels = _clip->channels(); | int channels = _clip->channels(); | ||||
| const int ratio = chunksize / pfchunksize; | const int ratio = chunksize / pfchunksize; | ||||
| /* locate to start position */ | |||||
| if ( fseek( fp, (s * channels / pfchunksize) * sizeof( Peak ), SEEK_CUR ) ) | |||||
| /* failed to seek... peaks not ready? */ | |||||
| return 0; | |||||
| if ( ratio == 1 ) | if ( ratio == 1 ) | ||||
| { | { | ||||
| int len = fread( peaks, sizeof( Peak ) * channels, npeaks, fp ); | int len = fread( peaks, sizeof( Peak ) * channels, npeaks, fp ); | ||||
| @@ -109,9 +111,6 @@ Peaks::read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize | |||||
| Peak *pbuf = new Peak[ ratio * channels ]; | Peak *pbuf = new Peak[ ratio * channels ]; | ||||
| /* locate to start position */ | |||||
| fseek( fp, (s * channels / pfchunksize) * sizeof( Peak ), SEEK_CUR ); | |||||
| size_t len = 0; | size_t len = 0; | ||||
| int i; | int i; | ||||
| @@ -208,7 +207,7 @@ Peaks::read_source_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) | |||||
| return i; | return i; | ||||
| } | } | ||||
| void | |||||
| int | |||||
| Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const | Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const | ||||
| { | { | ||||
| printf( "reading peaks %d @ %d\n", npeaks, chunksize ); | printf( "reading peaks %d @ %d\n", npeaks, chunksize ); | ||||
| @@ -220,6 +219,8 @@ Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const | |||||
| _peakbuf.buf = (peakdata*)realloc( _peakbuf.buf, sizeof( peakdata ) + (_peakbuf.size * sizeof( Peak )) ); | _peakbuf.buf = (peakdata*)realloc( _peakbuf.buf, sizeof( peakdata ) + (_peakbuf.size * sizeof( Peak )) ); | ||||
| } | } | ||||
| assert( s >= 0 ); | |||||
| _peakbuf.offset = s; | _peakbuf.offset = s; | ||||
| _peakbuf.buf->chunksize = chunksize; | _peakbuf.buf->chunksize = chunksize; | ||||
| @@ -229,6 +230,7 @@ Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const | |||||
| else | else | ||||
| _peakbuf.len = read_peakfile_peaks( _peakbuf.buf->data, s, npeaks, chunksize ); | _peakbuf.len = read_peakfile_peaks( _peakbuf.buf->data, s, npeaks, chunksize ); | ||||
| return _peakbuf.len; | |||||
| } | } | ||||
| /** Return the peak for the range of samples */ | /** Return the peak for the range of samples */ | ||||
| @@ -266,7 +268,9 @@ Peaks::open ( void ) | |||||
| int fd; | int fd; | ||||
| make_peaks( 256 ); | |||||
| /* Build peaks asyncronously */ | |||||
| if ( ! fork() ) | |||||
| exit( make_peaks( 256 ) ); | |||||
| if ( ( fd = ::open( peakname( filename ), O_RDONLY ) ) < 0 ) | if ( ( fd = ::open( peakname( filename ), O_RDONLY ) ) < 0 ) | ||||
| return false; | return false; | ||||
| @@ -344,7 +348,7 @@ Peaks::make_peaks ( int chunksize ) | |||||
| len = read_source_peaks( peaks, 1, chunksize ); | len = read_source_peaks( peaks, 1, chunksize ); | ||||
| fwrite( peaks, sizeof( peaks ), 1, fp ); | fwrite( peaks, sizeof( peaks ), 1, fp ); | ||||
| /* FIXME: GUI code shouldn't be here! */ | /* FIXME: GUI code shouldn't be here! */ | ||||
| Fl::check(); | |||||
| // Fl::check(); | |||||
| } | } | ||||
| while ( len ); | while ( len ); | ||||
| @@ -62,7 +62,7 @@ class Peaks | |||||
| mutable float _fpp; | mutable float _fpp; | ||||
| void read_peaks ( int s, int e, int npeaks, int chunksize ) const; | |||||
| int read_peaks ( int s, int e, int npeaks, int chunksize ) const; | |||||
| int read_source_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) const; | int read_source_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) const; | ||||
| int read_source_peaks ( Peak *peaks, int npeaks, int chunksize ) const; | int read_source_peaks ( Peak *peaks, int npeaks, int chunksize ) const; | ||||
| int read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) const; | int read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) const; | ||||
| @@ -562,9 +562,7 @@ Region::draw_box( int X, int Y, int W, int H ) | |||||
| fl_pop_clip(); | fl_pop_clip(); | ||||
| } | } | ||||
| /* Draw (part of) region. OX is pixel offset from start of timeline, X | |||||
| Y W and H are the portion of the widget to draw (arrived at by | |||||
| intersection of the clip and relative to OX) */ | |||||
| /** Draw (part of) region. X, Y, W and H are the rectangle we're clipped to. */ | |||||
| void | void | ||||
| Region::draw ( int X, int Y, int W, int H ) | Region::draw ( int X, int Y, int W, int H ) | ||||
| { | { | ||||
| @@ -572,6 +570,7 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| return; | return; | ||||
| if ( ! ( W > 0 && H > 0 ) ) | if ( ! ( W > 0 && H > 0 ) ) | ||||
| /* WTF? */ | |||||
| return; | return; | ||||
| int OX = scroll_x(); | int OX = scroll_x(); | ||||
| @@ -579,8 +578,14 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| if ( ox > OX + _track->w() || | if ( ox > OX + _track->w() || | ||||
| ox < OX && ox + abs_w() < OX ) | ox < OX && ox + abs_w() < OX ) | ||||
| /* not in viewport */ | |||||
| return; | return; | ||||
| if ( x() > X + W || x() + w() < X ) | |||||
| /* no coverage */ | |||||
| return; | |||||
| int rw = timeline->ts_to_x( _r->end - _r->start ); | int rw = timeline->ts_to_x( _r->end - _r->start ); | ||||
| // nframes_t end = _r->offset + ( _r->end - _r->start ); | // nframes_t end = _r->offset + ( _r->end - _r->start ); | ||||
| @@ -598,37 +603,45 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| int rx = x(); | int rx = x(); | ||||
| fl_push_clip( rx, Y, rw, H ); | |||||
| // fl_push_clip( rx, Y, rw, H ); | |||||
| /* get actual peak data */ | /* get actual peak data */ | ||||
| int channels; | int channels; | ||||
| int peaks; | int peaks; | ||||
| Peak *pbuf; | Peak *pbuf; | ||||
| const nframes_t start = _r->start + offset + timeline->x_to_ts( X - rx ); | |||||
| _clip->read_peaks( timeline->fpp(), | |||||
| start, | |||||
| start + timeline->x_to_ts( W ), | |||||
| &peaks, &pbuf, &channels ); | |||||
| assert( pbuf ); | |||||
| // const nframes_t start = _r->start + offset + timeline->x_to_ts( X - rx ); | |||||
| nframes_t start = _r->start + offset; | |||||
| /* draw fade curve outlines--this is only here because of crossfades */ | |||||
| draw_fade( _fade_in, Fade::In, true, X, W ); | |||||
| draw_fade( _fade_out, Fade::Out, true, X, W ); | |||||
| /* if ( X - rx > 0 ) */ | |||||
| /* start += timeline->x_to_ts( X - rx ); */ | |||||
| int ch = (h() - Fl::box_dh( box() )) / channels; | |||||
| for ( int i = 0; i < channels; ++i ) | |||||
| printf( "offset=%lu start=%lu\n", offset, start, X, rx ); | |||||
| if ( _clip->read_peaks( timeline->fpp(), | |||||
| start, | |||||
| start + timeline->x_to_ts( W ), | |||||
| &peaks, &pbuf, &channels ) ) | |||||
| { | { | ||||
| Peak *pb = pbuf + (peaks * i); | |||||
| /* scale it */ | |||||
| for ( int j = peaks; j--; ) | |||||
| assert( pbuf ); | |||||
| /* draw fade curve outlines--this is only here because of crossfades */ | |||||
| draw_fade( _fade_in, Fade::In, true, X, W ); | |||||
| draw_fade( _fade_out, Fade::Out, true, X, W ); | |||||
| int ch = (h() - Fl::box_dh( box() )) / channels; | |||||
| for ( int i = 0; i < channels; ++i ) | |||||
| { | { | ||||
| pb[ j ].min *= _scale; | |||||
| pb[ j ].max *= _scale; | |||||
| } | |||||
| Peak *pb = pbuf + (peaks * i); | |||||
| /* scale it */ | |||||
| for ( int j = peaks; j--; ) | |||||
| { | |||||
| pb[ j ].min *= _scale; | |||||
| pb[ j ].max *= _scale; | |||||
| } | |||||
| /* int fw = timeline->ts_to_x( fade.length ); */ | /* int fw = timeline->ts_to_x( fade.length ); */ | ||||
| @@ -640,21 +653,14 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| /* pb[ j ].max *= g; */ | /* pb[ j ].max *= g; */ | ||||
| /* } */ | /* } */ | ||||
| Waveform::draw( X, (y() + Fl::box_dy( box() )) + (i * ch), W, ch, | |||||
| pb, peaks, | |||||
| selected() ? fl_invert_color( _color ) : _color ); | |||||
| } | |||||
| delete[] pbuf; | |||||
| /* for ( int i = _clip->channels(); i--; ) */ | |||||
| /* Waveform::draw( rx, X, (y() + Fl::box_dy( box() )) + (i * ch), W, */ | |||||
| /* ch, _clip, i, timeline->fpp(), */ | |||||
| /* _r->start + offset, min( (_r->end - _r->start) - offset, _r->end), */ | |||||
| /* _scale, selected() ? fl_invert_color( _color ) : _color ); */ | |||||
| Waveform::draw( max( X, rx ), (y() + Fl::box_dy( box() )) + (i * ch), min( W, rw ), ch, | |||||
| pb, peaks, | |||||
| selected() ? fl_invert_color( _color ) : _color ); | |||||
| } | |||||
| delete[] pbuf; | |||||
| } | |||||
| timeline->draw_measure_lines( rx, Y, rw, H, _box_color ); | timeline->draw_measure_lines( rx, Y, rw, H, _box_color ); | ||||
| @@ -675,7 +681,7 @@ Region::draw ( int X, int Y, int W, int H ) | |||||
| 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 ); | ||||
| } | } | ||||
| fl_pop_clip(); | |||||
| // fl_pop_clip(); | |||||
| } | } | ||||
| @@ -103,7 +103,7 @@ Track::draw ( void ) | |||||
| for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | for ( list <Track_Widget *>::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) | ||||
| (*r)->draw( X, Y, W, H ); | |||||
| (*r)->draw( X, Y, W, H ); | |||||
| /* draw crossfades */ | /* draw crossfades */ | ||||
| @@ -42,7 +42,7 @@ bool Waveform::logarithmic = true; | |||||
| /** 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 | ||||
| Waveform::draw ( int X, int Y, int W, int H, | |||||
| Waveform::draw ( int X, int Y, int W, int H, | |||||
| Peak *pbuf, int peaks, | Peak *pbuf, int peaks, | ||||
| Fl_Color color ) | Fl_Color color ) | ||||
| { | { | ||||