Read peaks directly from source at high zoom levels.

This commit is contained in:
Jonathan Moore Liles 2008-02-16 21:32:31 -06:00
parent 0c9be68bcd
commit 720f024fa0
6 changed files with 82 additions and 16 deletions

6
Clip.H
View File

@ -25,16 +25,16 @@ typedef unsigned long nframes_t;
class Clip
{
char *_filename;
const char *_filename;
Peaks _peaks;
nframes_t _length; /* length of clip in samples */
public:
Clip ( const char *filename )
Clip ( const char *filename ) : _peaks( this )
{
_filename = NULL;
_filename = filename;
// FIXME: open file

71
Peaks.C
View File

@ -31,6 +31,7 @@
#include <sndfile.h>
#include "Clip.H"
void
Peaks::downsample ( int s, int e, float *mhi, float *mlo ) const
@ -63,6 +64,54 @@ Peaks::read ( int X, float *hi, float *lo ) const
downsample( start, end, hi, lo );
}
void
Peaks::read_peaks ( int s, int e, float *mhi, float *mlo ) const
{
/* this could be faster, but who cares. Don't zoom in so far! */
SNDFILE *in;
SF_INFO si;
memset( &si, 0, sizeof( si ) );
in = sf_open( _clip->name(), SFM_READ, &si );
/* if ( si.channels != 1 ) */
/* abort(); */
/* if ( si.samplerate != timeline.sample_rate ) */
/* abort(); */
sf_seek( in, s, SEEK_SET );
int chunksize = e - s;
float *fbuf = new float[ chunksize ];
size_t len;
/* read in a buffer */
len = sf_read_float( in, fbuf, chunksize );
Peak p;
p.max = -1.0;
p.min = 1.0;
for ( int i = 0; i < len; ++i )
{
if ( fbuf[i] > p.max )
p.max = fbuf[i];
if ( fbuf[i] < p.min )
p.min = fbuf[i];
}
sf_close( in );
delete fbuf;
*mhi = p.max;
*mlo = p.min;
}
/* virtual array. Index is a Pixel value, and it returns the
* (resampled) peaks for that pixel based on the current timeline
@ -75,16 +124,18 @@ Peaks::operator[] ( int X ) const
if ( timeline.fpp < _peaks->chunksize )
{
printf( "we need to a smaller chunksize! examine the source!\n" );
int start = timeline.x_to_ts( X );
int end = timeline.x_to_ts( X + 1 );
read_peaks( start, end, &p.max, &p.min );
}
else
{
int start = timeline.x_to_ts( X ) / _peaks->chunksize;
int end = timeline.x_to_ts( X + 1 ) / _peaks->chunksize;
int start = timeline.x_to_ts( X ) / _peaks->chunksize;
int end = timeline.x_to_ts( X + 1 ) / _peaks->chunksize;
/* int start = X * timeline.fpp; */
/* int end = (X + 1) * timeline.fpp; */
downsample( start, end, &p.max, &p.min );
downsample( start, end, &p.max, &p.min );
}
return p;
}
@ -179,6 +230,8 @@ Peaks::make_peaks ( const char *filename, int chunksize )
if ( si.channels != 1 )
abort();
if ( si.samplerate != timeline.sample_rate )
abort();
FILE *fp = fopen( peakname( filename ), "w" );
@ -216,7 +269,7 @@ Peaks::make_peaks ( const char *filename, int chunksize )
while ( len == chunksize );
fclose( fp );
sf_close( in );
delete fbuf;
}

10
Peaks.H
View File

@ -26,6 +26,7 @@ struct Peak {
float max;
};
class Clip;
class Peaks
{
@ -35,19 +36,26 @@ class Peaks
Peak data[];
};
Clip *_clip;
peaks *_peaks;
size_t _len;
void read_peaks ( int s, int e, float *mhi, float *mlo ) const;
public:
Peaks ( void )
Peaks ( Clip *c )
{
_peaks = new peaks;
_peaks->chunksize = 0;
// _peaks->data = NULL;
_len = 0;
_clip = c;
}
void downsample ( int s, int e, float *mhi, float *mlo ) const;

View File

@ -237,9 +237,10 @@ Region::draw ( void )
// fl_pop_clip();
fl_color( FL_RED );
fl_line( x() - _start, y(), x() - _start, y() + h() );
fl_line( x() + w() - _end, y(), x() + w() - _end, y() + h() );
/* fl_color( FL_RED ); */
/* fl_line( x() - timeline.ts_to_x( _start ), y(), x() - timeline.ts_to_x( _start ), y() + h() ); */
/* fl_line( x() + w() - _end, y(), x() + w() - _end, y() + h() ); */
draw_label();

View File

@ -28,6 +28,7 @@ struct Timeline {
float fpp; /* frames per pixel */
nframes_t sample_rate;
int
ts_to_x( nframes_t ts )

3
main.C
View File

@ -67,6 +67,9 @@ main ( int argc, char **argv )
timeline.scroll = new Fl_Scroll( 0, 24, 800, 600 - 24 );
timeline.fpp = 256;
timeline.sample_rate = 44100;
Fl_Pack *tracks = new Fl_Pack( 0, 0, 5000, 5000 );
tracks->type( Fl_Pack::VERTICAL );