diff --git a/Timeline/Audio_File.H b/Timeline/Audio_File.H index 63d9f5d..77e940b 100644 --- a/Timeline/Audio_File.H +++ b/Timeline/Audio_File.H @@ -53,6 +53,10 @@ public: _length = _channels = 0; } + virtual ~Audio_File ( ) + { + } + static Audio_File *from_file ( const char *filename ); Peaks const * peaks ( ) { return _peaks; } diff --git a/Timeline/Audio_File_SF.C b/Timeline/Audio_File_SF.C index 6a6c276..02c05cc 100644 --- a/Timeline/Audio_File_SF.C +++ b/Timeline/Audio_File_SF.C @@ -103,22 +103,31 @@ Audio_File_SF::create ( const char *filename, nframes_t samplerate, int channels bool Audio_File_SF::open ( void ) { + SF_INFO si; -/* SF_INFO si; */ + assert( _in == NULL ); -/* memset( &si, 0, sizeof( si ) ); */ + memset( &si, 0, sizeof( si ) ); -/* if ( ! ( _in = sf_open( _filename, SFM_READ, &si ) ) ) */ -/* return false; */ + if ( ! ( _in = sf_open( _filename, SFM_READ, &si ) ) ) + return false; - seek( 0 ); + _current_read = 0; + _length = si.frames; + _samplerate = si.samplerate; + _channels = si.channels; + +// seek( 0 ); return true; } void Audio_File_SF::close ( void ) { -// sf_close( _in ); + if ( _in ) + sf_close( _in ); + + _in = NULL; } void diff --git a/Timeline/Audio_File_SF.H b/Timeline/Audio_File_SF.H index 78cfc59..2d5413d 100644 --- a/Timeline/Audio_File_SF.H +++ b/Timeline/Audio_File_SF.H @@ -36,6 +36,12 @@ public: static Audio_File_SF *from_file ( const char *filename ); static Audio_File_SF *create ( const char *filename, nframes_t samplerate, int channels, const char *format ); + ~Audio_File_SF ( ) + { + /* stupid C++ */ + close(); + } + bool open ( void ); void close ( void ); void seek ( nframes_t offset ); diff --git a/Timeline/Disk_Stream.C b/Timeline/Disk_Stream.C index 441c1b4..cc21687 100644 --- a/Timeline/Disk_Stream.C +++ b/Timeline/Disk_Stream.C @@ -78,11 +78,6 @@ Disk_Stream::Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes Disk_Stream::~Disk_Stream ( ) { - - /* stop the IO thread */ - _terminate = true; - pthread_join( _thread, NULL ); - /* it isn't safe to do all this with the RT thread running */ engine->lock(); @@ -96,6 +91,14 @@ Disk_Stream::~Disk_Stream ( ) engine->unlock(); } +/** stop the IO thread, block until it finishes. */ +void +Disk_Stream::shutdown ( void ) +{ + _terminate = true; + pthread_join( _thread, NULL ); +} + Audio_Track * Disk_Stream::track ( void ) { @@ -119,12 +122,6 @@ Disk_Stream::resize ( nframes_t nframes ) } -/* void */ -/* DIsk_Stream::shutdown ( void ) */ -/* { */ -/* pthread_join( &_thread, NULL ); */ -/* } */ - /* static wrapper */ void * Disk_Stream::disk_thread ( void *arg ) diff --git a/Timeline/Disk_Stream.H b/Timeline/Disk_Stream.H index 11b6682..a09aaa7 100644 --- a/Timeline/Disk_Stream.H +++ b/Timeline/Disk_Stream.H @@ -94,6 +94,7 @@ public: /* bool seek_pending ( void ); */ void run ( void ); + void shutdown ( void ); virtual nframes_t process ( nframes_t nframes ) = 0; diff --git a/Timeline/Record_DS.C b/Timeline/Record_DS.C index 9658966..4e2cd1d 100644 --- a/Timeline/Record_DS.C +++ b/Timeline/Record_DS.C @@ -123,15 +123,66 @@ Record_DS::disk_thread ( void ) printf( "IO thread terminating.\n" ); + delete[] cbuf; delete[] buf; } + +/** begin recording */ +/* FIXME: we need to make note of the exact frame we were on when recording began */ +void +Record_DS::start ( nframes_t frame ) +{ + /* FIXME: flush buffers here? */ + + if ( _recording ) + { + printf( "programming error: attempt to start recording while recording is still in progress\n" ); + return; + } + + _af = Audio_File_SF::create( "testing.wav", 48000, channels(), "Wav/24" ); + + _frame = frame; + + run(); + + _recording = true; + +} + +/** finalize the recording process. */ +void +Record_DS::stop ( nframes_t frame ) +{ + + if ( ! _recording ) + { + printf( "programming error: attempt to stop recording when no recording is being made\n" ); + return; + } + + shutdown(); + + /* FIXME: flush buffers here? */ + delete _af; + _af = NULL; + + _recording = false; + + printf( "recording finished\n" ); +} + + /* THREAD: RT */ -/** take a single block from the ringbuffers and send it out the - * attached track's ports */ +/** read from the attached track's ports and stuff the ringbuffers */ nframes_t Record_DS::process ( nframes_t nframes ) { + + if ( ! _recording ) + return 0; + const size_t block_size = nframes * sizeof( sample_t ); // printf( "process: %lu %lu %lu\n", _frame, _frame + nframes, nframes ); diff --git a/Timeline/Record_DS.H b/Timeline/Record_DS.H index 5109310..238c0ec 100644 --- a/Timeline/Record_DS.H +++ b/Timeline/Record_DS.H @@ -27,6 +27,8 @@ class Audio_File; class Record_DS : public Disk_Stream { + volatile bool _recording; + Audio_File_SF *_af; /* capture file */ void write_block ( sample_t *buf, nframes_t nframes ); @@ -37,19 +39,17 @@ public: Record_DS ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : Disk_Stream( th, frame_rate, nframes, channels ) { - /* FIXME: we need our semaphore set to 0, no? */ - - _af = Audio_File_SF::create( "testing.wav", 48000, 1, "Wav/24" ); - sem_destroy( &_blocks ); sem_init( &_blocks, 0, 0 ); - run(); + _recording = false; } /* bool seek_pending ( void ); */ /* void seek ( nframes_t frame ); */ + void start ( nframes_t frame ); + void stop ( nframes_t frame ); nframes_t process ( nframes_t nframes ); }; diff --git a/Timeline/Track_Header.C b/Timeline/Track_Header.C index ad59847..f5e4516 100644 --- a/Timeline/Track_Header.C +++ b/Timeline/Track_Header.C @@ -19,6 +19,7 @@ #include "Track_Header.H" +#include "Transport.H" #include "Playback_DS.H" #include "Record_DS.H" @@ -59,8 +60,11 @@ Track_Header::cb_button ( Fl_Widget *w ) printf( "FIXME: inform mixer here\n" ); if ( w == record_button ) { - - + /* FIXME: wrong place for this! */ + if ( record_button->value() ) + record_ds->start( transport.frame ); + else + record_ds->stop( transport.frame ); } else if ( w == take_menu ) @@ -114,10 +118,14 @@ Track_Header::Track_Header ( int X, int Y, int W, int H, const char *L ) : input.push_back( Port( strdup( pname ), Port::Input ) ); + snprintf( pname, sizeof( pname ), "in-%d", ni++ ); + + input.push_back( Port( strdup( pname ), Port::Input ) ); + } playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), 1 ); - record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), 1 ); + record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), 2 ); Fl_Group::size( w(), height() );