Fix pending peaks timers.

pull/3/head
Jonathan Moore Liles 2008-05-11 12:18:51 -05:00
parent f12363340e
commit 17790c13c1
4 changed files with 78 additions and 30 deletions

View File

@ -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 )
{
Rectangle *r = (Rectangle*)v;
Peaks_Redraw_Request *r = (Peaks_Redraw_Request*)v;
printf( "damaging from timeout\n" );
timeline->damage( FL_DAMAGE_ALL, r->x, r->y, r->w, r->h );
r->region->peaks_pending_cb( r );
}
delete r;
void
Audio_Region::peaks_pending_cb ( Peaks_Redraw_Request *r )
{
int npeaks = timeline->ts_to_x( r->end - r->start );
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;
}
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 ); */

View File

@ -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;

View File

@ -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 {

View File

@ -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;