@@ -31,6 +31,8 @@ typedef float sample_t; | |||||
#include <map> | #include <map> | ||||
using namespace std; | using namespace std; | ||||
class Peak_Writer; | |||||
class Audio_File | class Audio_File | ||||
{ | { | ||||
static map <string, Audio_File*> _open_files; | static map <string, Audio_File*> _open_files; | ||||
@@ -45,6 +47,8 @@ protected: | |||||
Peaks *_peaks; | Peaks *_peaks; | ||||
Peak_Writer *_peak_writer; | |||||
public: | public: | ||||
Audio_File ( ) | Audio_File ( ) | ||||
@@ -27,6 +27,8 @@ | |||||
#include <assert.h> | #include <assert.h> | ||||
#include "Peaks.H" | |||||
Audio_File_SF * | Audio_File_SF * | ||||
Audio_File_SF::from_file ( const char *filename ) | Audio_File_SF::from_file ( const char *filename ) | ||||
{ | { | ||||
@@ -97,6 +99,9 @@ Audio_File_SF::create ( const char *filename, nframes_t samplerate, int channels | |||||
c->_in = out; | c->_in = out; | ||||
/* FIXME: 256 ? */ | |||||
c->_peak_writer = new Peak_Writer( filename, 256, channels ); | |||||
return c; | return c; | ||||
} | } | ||||
@@ -127,6 +132,9 @@ Audio_File_SF::close ( void ) | |||||
if ( _in ) | if ( _in ) | ||||
sf_close( _in ); | sf_close( _in ); | ||||
if ( _peak_writer ) | |||||
delete _peak_writer; | |||||
_in = NULL; | _in = NULL; | ||||
} | } | ||||
@@ -194,5 +202,7 @@ Audio_File_SF::read ( sample_t *buf, int channel, nframes_t start, nframes_t end | |||||
nframes_t | nframes_t | ||||
Audio_File_SF::write ( sample_t *buf, nframes_t nframes ) | Audio_File_SF::write ( sample_t *buf, nframes_t nframes ) | ||||
{ | { | ||||
_peak_writer->write( buf, nframes ); | |||||
return sf_writef_float( _in, buf, nframes ); | return sf_writef_float( _in, buf, nframes ); | ||||
} | } |
@@ -43,6 +43,17 @@ | |||||
Peaks::peakbuffer Peaks::_peakbuf; | Peaks::peakbuffer Peaks::_peakbuf; | ||||
static | |||||
const char * | |||||
peakname ( const char *filename ) | |||||
{ | |||||
static char file[512]; | |||||
snprintf( file, 512, "%s.peak", filename ); | |||||
return (const char*)&file; | |||||
} | |||||
/** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be | /** Prepare a buffer of peaks from /s/ to /e/ for reading. Must be | ||||
* called before any calls to operator[] */ | * called before any calls to operator[] */ | ||||
int | int | ||||
@@ -253,15 +264,6 @@ Peaks::read_peaks ( nframes_t s, nframes_t e, int npeaks, int chunksize ) const | |||||
/* return p; */ | /* return p; */ | ||||
/* } */ | /* } */ | ||||
const char * | |||||
Peaks::peakname ( const char *filename ) const | |||||
{ | |||||
static char file[512]; | |||||
snprintf( file, 512, "%s.peak", filename ); | |||||
return (const char*)&file; | |||||
} | |||||
bool | bool | ||||
Peaks::open ( void ) | Peaks::open ( void ) | ||||
@@ -271,7 +273,7 @@ Peaks::open ( void ) | |||||
int fd; | int fd; | ||||
if ( ! current() ) | if ( ! current() ) | ||||
/* Build peaks asyncronously */ | |||||
/* Build peaks asyncronously */ | |||||
if ( ! fork() ) | if ( ! fork() ) | ||||
exit( make_peaks( 256 ) ); | exit( make_peaks( 256 ) ); | ||||
@@ -318,7 +320,7 @@ Peaks::current ( void ) const | |||||
/* FIXME: we need to work out a way to run this in another thread and | /* FIXME: we need to work out a way to run this in another thread and | ||||
possibly stream back the data to the GUI */ | |||||
possibly stream back the data to the GUI */ | |||||
/** build peaks file for /filename/ if necessary */ | /** build peaks file for /filename/ if necessary */ | ||||
bool | bool | ||||
Peaks::make_peaks ( int chunksize ) | Peaks::make_peaks ( int chunksize ) | ||||
@@ -387,3 +389,65 @@ Peaks::make_peaks ( int chunksize ) | |||||
/* return s; */ | /* return s; */ | ||||
/* } */ | /* } */ | ||||
Peak_Writer::Peak_Writer ( const char *filename, int chunksize, int channels ) | |||||
{ | |||||
_channels = channels; | |||||
_chunksize = chunksize; | |||||
_peak = new Peak[ channels ]; | |||||
memset( _peak, 0, sizeof( Peak ) * channels ); | |||||
if ( ! ( _fp = fopen( peakname( filename ), "w" ) ) ) | |||||
/* error! */; | |||||
write_header(); | |||||
} | |||||
Peak_Writer::~Peak_Writer ( ) | |||||
{ | |||||
fclose( _fp ); | |||||
delete _peak; | |||||
} | |||||
void | |||||
Peak_Writer::write_header ( void ) | |||||
{ | |||||
fprintf( _fp, "NON-PEAKS%2d%2d", VERSION_MAJOR, VERSION_MINOR ); | |||||
int data[] = { _chunksize, _channels, sizeof( Peak ) }; | |||||
fwrite( &data, sizeof( data ), 1, _fp ); | |||||
} | |||||
/** append peaks for samples in /buf/ to peakfile */ | |||||
void | |||||
Peak_Writer::write ( sample_t *buf, nframes_t nframes ) | |||||
{ | |||||
for ( int i = _chunksize; nframes--; --i, buf += _channels ) | |||||
{ | |||||
for ( int j = 0; j < _channels; ++j ) | |||||
{ | |||||
Peak *p = _peak + j; | |||||
if ( *buf > p->max ) | |||||
p->max = *buf; | |||||
if ( *buf < p->min ) | |||||
p->min = *buf; | |||||
} | |||||
if ( ! i ) | |||||
{ | |||||
fwrite( _peak, sizeof( Peak ), _channels, _fp ); | |||||
memset( _peak, 0, sizeof( Peak ) * _channels ); | |||||
i = _chunksize; | |||||
} | |||||
} | |||||
} |
@@ -67,7 +67,7 @@ class Peaks | |||||
int read_source_peaks ( Peak *peaks, 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; | int read_peakfile_peaks ( Peak *peaks, nframes_t s, int npeaks, int chunksize ) const; | ||||
const char *peakname ( const char *filename ) const; | |||||
// const char *peakname ( const char *filename ) const; | |||||
// Peaks ( ); | // Peaks ( ); | ||||
@@ -104,3 +104,27 @@ public: | |||||
Peak & operator[] ( int X ) const; | Peak & operator[] ( int X ) const; | ||||
}; | }; | ||||
#include <stdio.h> | |||||
class Peak_Writer | |||||
{ | |||||
static const int VERSION_MAJOR = 0; | |||||
static const int VERSION_MINOR = 1; | |||||
FILE *_fp; | |||||
Peak *_peak; | |||||
int _chunksize; | |||||
int _channels; | |||||
public: | |||||
Peak_Writer ( const char *filename, int chunksize, int channels ); | |||||
~Peak_Writer ( ); | |||||
void write_header ( void ); | |||||
void write ( sample_t *buf, nframes_t nframes ); | |||||
}; |
@@ -142,7 +142,6 @@ Record_DS::start ( nframes_t frame ) | |||||
} | } | ||||
_af = Audio_File_SF::create( "testing.wav", 48000, channels(), "Wav/24" ); | _af = Audio_File_SF::create( "testing.wav", 48000, channels(), "Wav/24" ); | ||||
_frame = frame; | _frame = frame; | ||||
run(); | run(); | ||||
@@ -23,6 +23,7 @@ | |||||
#include "Audio_File_SF.H" | #include "Audio_File_SF.H" | ||||
class Audio_File; | class Audio_File; | ||||
class Peak_Writer; | |||||
class Record_DS : public Disk_Stream | class Record_DS : public Disk_Stream | ||||
{ | { | ||||