From 17790c13c132689974321d0f092a09d13b0150d4 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sun, 11 May 2008 12:18:51 -0500 Subject: [PATCH] Fix pending peaks timers. --- Timeline/Audio_Region.C | 50 +++++++++++++++++++++++++++++---------- Timeline/Audio_Region.H | 5 ++++ Timeline/Peaks.C | 52 +++++++++++++++++++++++++++-------------- Timeline/Peaks.H | 1 + 4 files changed, 78 insertions(+), 30 deletions(-) diff --git a/Timeline/Audio_Region.C b/Timeline/Audio_Region.C index 834ed04..5d0425e 100644 --- a/Timeline/Audio_Region.C +++ b/Timeline/Audio_Region.C @@ -448,15 +448,42 @@ Audio_Region::draw_fade ( const Fade &fade, Fade::fade_dir_e dir, bool line, int fl_pop_matrix(); } -static void -damager ( void *v ) +struct Peaks_Redraw_Request { + + Audio_Region *region; + + nframes_t start; + nframes_t end; + + Peaks_Redraw_Request ( Audio_Region *region, nframes_t start, nframes_t end ) : region( region ), start( start), end( end ) + { + } +}; + +/* static wrapper */ +void +Audio_Region::peaks_pending_cb ( void *v ) +{ + Peaks_Redraw_Request *r = (Peaks_Redraw_Request*)v; + + r->region->peaks_pending_cb( r ); +} + +void +Audio_Region::peaks_pending_cb ( Peaks_Redraw_Request *r ) { - Rectangle *r = (Rectangle*)v; + int npeaks = timeline->ts_to_x( r->end - r->start ); - printf( "damaging from timeout\n" ); - timeline->damage( FL_DAMAGE_ALL, r->x, r->y, r->w, r->h ); + if ( _clip->peaks()->ready( r->start, npeaks, timeline->fpp() ) ) + { + printf( "damaging from timeout\n" ); + /* FIXME: only need to damage the affected area! */ + timeline->damage( FL_DAMAGE_ALL, x(), y(), w(), h() ); - delete r; + delete r; + } + else + Fl::repeat_timeout( 0.1f, &Audio_Region::peaks_pending_cb, (void*)r ); } void @@ -553,9 +580,11 @@ Audio_Region::draw ( void ) const int peaks_needed = min( timeline->ts_to_x( _clip->length() - start ), W ); + const nframes_t end = start + timeline->x_to_ts( peaks_needed ); + if ( _clip->read_peaks( timeline->fpp(), start, - start + timeline->x_to_ts( peaks_needed ), + end, &peaks, &pbuf, &channels ) && peaks ) { @@ -603,13 +632,10 @@ Audio_Region::draw ( void ) if ( peaks < peaks_needed ) { /* couldn't read peaks--perhaps they're being generated. Try again later. */ - - /* commented out for testing. */ -// Fl::add_timeout( 0.1f, damager, new Rectangle( X, y(), W, h() ) ); - + Fl::add_timeout( 0.1f, &Audio_Region::peaks_pending_cb, + new Peaks_Redraw_Request( this, start + timeline->x_to_ts( peaks ), end ) ); } - /* FIXME: only draw as many as are necessary! */ timeline->draw_measure_lines( X, Y, W, H, _box_color ); /* fl_color( FL_BLACK ); */ diff --git a/Timeline/Audio_Region.H b/Timeline/Audio_Region.H index 61d4d80..7befe17 100644 --- a/Timeline/Audio_Region.H +++ b/Timeline/Audio_Region.H @@ -28,6 +28,7 @@ #include "Sequence_Region.H" +class Peaks_Redraw_Request; class Audio_Region : public Sequence_Region { @@ -103,6 +104,10 @@ private: friend class Track; /* for _clip */ + + static void peaks_pending_cb ( void *v ); + void peaks_pending_cb ( Peaks_Redraw_Request *r ); + protected: virtual void get ( Log_Entry &e ) const; diff --git a/Timeline/Peaks.C b/Timeline/Peaks.C index 348c461..ee649f5 100644 --- a/Timeline/Peaks.C +++ b/Timeline/Peaks.C @@ -142,6 +142,7 @@ class Peakfile nframes_t _length; /* length, in frames, of the clip this peakfile represents */ const char *_name; size_t _offset; + int _blocks; struct block_descriptor { @@ -163,11 +164,11 @@ public: Peakfile ( ) { + _blocks = 0; _fp = NULL; _offset = 0; _chunksize = 0; _channels = 0; - _length = 0; _name =NULL; } @@ -177,9 +178,10 @@ public: close(); } + int blocks ( void ) const { return _blocks; } /** find the best block for /chunksize/ */ void - find_block ( nframes_t chunksize ) + scan ( nframes_t chunksize ) { rewind( _fp ); clearerr( _fp ); @@ -230,7 +232,7 @@ public: } // DMESSAGE( "using peakfile block for chunksize %lu", _chunksize ); - + _blocks = blocks.size(); _offset = ftell( _fp ); } @@ -248,14 +250,17 @@ public: fstat( fileno( _fp ), &st ); - return st.st_size / sizeof( Peak ); + return ( st.st_size - sizeof( peakfile_block_header ) ) / sizeof( Peak ); } /** returns true if the peakfile contains /npeaks/ peaks starting at sample /s/ */ bool - contains ( nframes_t start, nframes_t npeaks ) + ready ( nframes_t start, nframes_t npeaks ) { - return frame_to_peak( start ) + npeaks <= this->npeaks(); + if ( _blocks > 1 ) + return true; + else + return this->npeaks() > frame_to_peak( start ) + npeaks; } /** given soundfile name /name/, try to open the best peakfile for /chunksize/ */ @@ -269,7 +274,7 @@ public: if ( ! ( _fp = fopen( peakname( name ), "r" ) ) ) return false; - find_block( chunksize ); + scan( chunksize ); assert( _chunksize ); @@ -283,7 +288,7 @@ public: _chunksize = 0; _channels = channels; - find_block( chunksize ); + scan( chunksize ); assert( _chunksize ); } @@ -368,6 +373,16 @@ public: } }; +bool +Peaks::ready ( nframes_t s, int npeaks, nframes_t chunksize ) const +{ + Peakfile _peakfile; + + if ( ! _peakfile.open( _clip->name(), chunksize, _clip->channels() ) ) + return false; + + return _peakfile.ready( s, npeaks ); +} int Peaks::read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, nframes_t chunksize ) const @@ -390,14 +405,15 @@ Peaks::read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, nframes_t chu if ( ! _peakfile.open( _clip->name(), chunksize, _clip->channels() ) ) return 0; - else if ( ! _peakfile.contains( s, npeaks ) ) - { - /* the best peakfile for this chunksize doesn't have the - * peaks we need. Perhaps it's still being constructed, - * try the next best, then give up. */ - if ( ! _peakfile.open( _clip->name(), chunksize >> 1, _clip->channels() ) ) - return 0; - } + +/* else if ( ! _peakfile.contains( s, npeaks ) ) */ +/* { */ +/* /\* the best peakfile for this chunksize doesn't have the */ +/* * peaks we need. Perhaps it's still being constructed, */ +/* * try the next best, then give up. *\/ */ +/* if ( ! _peakfile.open( _clip->name(), chunksize >> 1, _clip->channels() ) ) */ +/* return 0; */ +/* } */ return _peakfile.read_peaks( peaks, s, npeaks, chunksize ); @@ -679,6 +695,8 @@ Peaks::Builder::write_block_header ( nframes_t chunksize ) fwrite( &bh, sizeof( bh ), 1, fp ); last_block_pos = ftell( fp ); + + fflush( fp ); } /** generate additional cache levels for a peakfile with only 1 block (ie. that of a new capture) */ @@ -719,8 +737,6 @@ Peaks::Builder::make_peaks_mipmap ( void ) write_block_header( cs ); - fflush( fp ); - size_t len; nframes_t s = 0; do { diff --git a/Timeline/Peaks.H b/Timeline/Peaks.H index feacdb9..4e20eb1 100644 --- a/Timeline/Peaks.H +++ b/Timeline/Peaks.H @@ -132,6 +132,7 @@ public: int fill_buffer ( float fpp, nframes_t s, nframes_t e ) const; void read ( int X, float *hi, float *lo ) const; + bool ready ( nframes_t s, int npeaks, nframes_t chunksize ) const; bool current ( void ) const; bool make_peaks ( void ) const;