Stream peaks to disk during capture.
This commit is contained in:
parent
ed9a1aaf5b
commit
99e93c575e
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue