From 3b40b8a093e31c4cc424bc7cf71a25617d4d0ef7 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Thu, 17 Apr 2008 08:27:35 -0500 Subject: [PATCH] Fix some bugs in peak reading/drawing. --- Timeline/Audio_File.C | 4 +++ Timeline/Peaks.C | 24 +++++++------ Timeline/Peaks.H | 2 +- Timeline/Region.C | 78 +++++++++++++++++++++++-------------------- Timeline/Track.C | 2 +- Timeline/Waveform.C | 2 +- 6 files changed, 63 insertions(+), 49 deletions(-) diff --git a/Timeline/Audio_File.C b/Timeline/Audio_File.C index 18539e3..d821666 100644 --- a/Timeline/Audio_File.C +++ b/Timeline/Audio_File.C @@ -62,6 +62,10 @@ Audio_File::read_peaks( float fpp, nframes_t start, nframes_t end, int *peaks, P { Peaks pk; + *peaks = 0; + *channels = 0; + *pbuf = NULL; + pk.clip( this ); if ( ! pk.open() ) diff --git a/Timeline/Peaks.C b/Timeline/Peaks.C index edf6149..e3a46a3 100644 --- a/Timeline/Peaks.C +++ b/Timeline/Peaks.C @@ -50,10 +50,7 @@ Peaks::fill_buffer ( float fpp, int s, int e ) const { _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(); 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 ) { 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 ]; - /* locate to start position */ - fseek( fp, (s * channels / pfchunksize) * sizeof( Peak ), SEEK_CUR ); - size_t len = 0; int i; @@ -208,7 +207,7 @@ Peaks::read_source_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) return i; } -void +int Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const { 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 )) ); } + assert( s >= 0 ); + _peakbuf.offset = s; _peakbuf.buf->chunksize = chunksize; @@ -229,6 +230,7 @@ Peaks::read_peaks ( int s, int e, int npeaks, int chunksize ) const else _peakbuf.len = read_peakfile_peaks( _peakbuf.buf->data, s, npeaks, chunksize ); + return _peakbuf.len; } /** Return the peak for the range of samples */ @@ -266,7 +268,9 @@ Peaks::open ( void ) int fd; - make_peaks( 256 ); + /* Build peaks asyncronously */ + if ( ! fork() ) + exit( make_peaks( 256 ) ); if ( ( fd = ::open( peakname( filename ), O_RDONLY ) ) < 0 ) return false; @@ -344,7 +348,7 @@ Peaks::make_peaks ( int chunksize ) len = read_source_peaks( peaks, 1, chunksize ); fwrite( peaks, sizeof( peaks ), 1, fp ); /* FIXME: GUI code shouldn't be here! */ - Fl::check(); +// Fl::check(); } while ( len ); diff --git a/Timeline/Peaks.H b/Timeline/Peaks.H index 880029e..5f35be0 100644 --- a/Timeline/Peaks.H +++ b/Timeline/Peaks.H @@ -62,7 +62,7 @@ class Peaks 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, int npeaks, int chunksize ) const; int read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) const; diff --git a/Timeline/Region.C b/Timeline/Region.C index 28f103f..45bb381 100644 --- a/Timeline/Region.C +++ b/Timeline/Region.C @@ -562,9 +562,7 @@ Region::draw_box( int X, int Y, int W, int H ) 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 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; if ( ! ( W > 0 && H > 0 ) ) + /* WTF? */ return; int OX = scroll_x(); @@ -579,8 +578,14 @@ Region::draw ( int X, int Y, int W, int H ) if ( ox > OX + _track->w() || ox < OX && ox + abs_w() < OX ) + /* not in viewport */ return; + if ( x() > X + W || x() + w() < X ) + /* no coverage */ + return; + + int rw = timeline->ts_to_x( _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(); - fl_push_clip( rx, Y, rw, H ); +// fl_push_clip( rx, Y, rw, H ); /* get actual peak data */ int channels; int peaks; 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 ); */ @@ -640,21 +653,14 @@ Region::draw ( int X, int Y, int W, int H ) /* 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 ); @@ -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 ); } - fl_pop_clip(); +// fl_pop_clip(); } diff --git a/Timeline/Track.C b/Timeline/Track.C index d4f186c..c867b94 100644 --- a/Timeline/Track.C +++ b/Timeline/Track.C @@ -103,7 +103,7 @@ Track::draw ( void ) for ( list ::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) - (*r)->draw( X, Y, W, H ); + (*r)->draw( X, Y, W, H ); /* draw crossfades */ diff --git a/Timeline/Waveform.C b/Timeline/Waveform.C index 6535be9..eef0565 100644 --- a/Timeline/Waveform.C +++ b/Timeline/Waveform.C @@ -42,7 +42,7 @@ bool Waveform::logarithmic = true; /** draw a portion of /clip/'s waveform. coordinates are the portion to draw */ 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, Fl_Color color ) {