From 31b449c24b1aa0c4e138c40e89e104702eebc17f Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sat, 16 Feb 2008 20:36:17 -0600 Subject: [PATCH] Use libsndfile. Actually generate peak data. --- Clip.H | 1 - Makefile | 3 +- Peaks.C | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- Peaks.H | 2 ++ main.C | 4 +-- 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/Clip.H b/Clip.H index 5230c6f..7f38bf6 100644 --- a/Clip.H +++ b/Clip.H @@ -19,7 +19,6 @@ #pragma once - typedef unsigned long nframes_t; #include "Peaks.H" diff --git a/Makefile b/Makefile index 56e5f92..66aaebd 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ CXXFLAGS=-ggdb -Wall -O0 -LIBS=`fltk-config --ldflags` +#LIBS=-L/usr/lib/sox -I/usr/include/sox -lsox -lsfx +LIBS=-lsndfile `fltk-config --ldflags` # CXXFLAGS=`fltk-config -cxxflags` SRCS= Waveform.C Region.C Peaks.C main.C diff --git a/Peaks.C b/Peaks.C index cb1e889..c1e2793 100644 --- a/Peaks.C +++ b/Peaks.C @@ -29,6 +29,9 @@ #include #include +#include + + void Peaks::downsample ( int s, int e, float *mhi, float *mlo ) const { @@ -86,18 +89,30 @@ Peaks::operator[] ( int X ) const return p; } +static +const char * +peakname ( const char *filename ) +{ + static char file[512]; + + snprintf( file, 512, "%s.peak", filename ); + + return (const char*)&file; +} bool Peaks::open ( const char *filename ) { - char file[512]; - - snprintf( file, 512, "%s.peak", filename ); - int fd; - if ( ( fd = ::open( file, O_RDONLY ) ) < 0 ) + +try_again: + if ( ( fd = ::open( peakname( filename ), O_RDONLY ) ) < 0 ) { /* generate peaks here */ + if ( make_peaks( filename, 256 ) ) + goto try_again; + else + return false; } { @@ -117,3 +132,68 @@ Peaks::open ( const char *filename ) return true; } + + +void +long_to_float( long *buf, int len ) +{ + for ( int i = len; i--; ) + *((float*)buf) = *buf / 32768; +} + +bool +Peaks::make_peaks ( const char *filename, int chunksize ) +{ + SNDFILE *in; + +// sox_format_init(); + + + SF_INFO si; + memset( &si, 0, sizeof( si ) ); + + in = sf_open( filename, SFM_READ, &si ); + + if ( si.channels != 1 ) + abort(); + + FILE *fp = fopen( peakname( filename ), "w" ); + + if ( fp == NULL ) + { + sf_close( in ); + /* return fals */ + return false; + } + + /* write chunksize first */ + fwrite( &chunksize, sizeof( int ), 1, fp ); + + float *fbuf = new float[ chunksize ]; + + size_t len; + do { + /* 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]; + } + + fwrite( &p, sizeof( Peak ), 1, fp ); + } + while ( len == chunksize ); + + fclose( fp ); + + sf_close( in ); + +} diff --git a/Peaks.H b/Peaks.H index 8d54052..b4812db 100644 --- a/Peaks.H +++ b/Peaks.H @@ -54,6 +54,8 @@ public: void read ( int X, float *hi, float *lo ) const; bool open ( const char *filename ); + bool make_peaks ( const char *filename, int chunksize ); + Peak & operator[] ( int X ) const; }; diff --git a/main.C b/main.C index d458a48..8769c78 100644 --- a/main.C +++ b/main.C @@ -65,7 +65,7 @@ main ( int argc, char **argv ) Fl_Double_Window *main_window = new Fl_Double_Window( 0, 0, 800, 600 ); timeline.scroll = new Fl_Scroll( 0, 24, 800, 600 - 24 ); - timeline.fpp = 1; + timeline.fpp = 256; Fl_Pack *tracks = new Fl_Pack( 0, 0, 5000, 5000 ); tracks->type( Fl_Pack::VERTICAL ); @@ -82,7 +82,7 @@ main ( int argc, char **argv ) // Region *wave = new Region( 0, 0, 5000, 100, "foo" ); - Region *wave = new Region( new Clip( "foo.wav" ) ); + Region *wave = new Region( new Clip( "streambass8.wav" ) ); wave->resize( 0, 0, 500, 100 );