| @@ -53,6 +53,10 @@ public: | |||||
| _length = _channels = 0; | _length = _channels = 0; | ||||
| } | } | ||||
| virtual ~Audio_File ( ) | |||||
| { | |||||
| } | |||||
| static Audio_File *from_file ( const char *filename ); | static Audio_File *from_file ( const char *filename ); | ||||
| Peaks const * peaks ( ) { return _peaks; } | Peaks const * peaks ( ) { return _peaks; } | ||||
| @@ -103,22 +103,31 @@ Audio_File_SF::create ( const char *filename, nframes_t samplerate, int channels | |||||
| bool | bool | ||||
| Audio_File_SF::open ( void ) | Audio_File_SF::open ( void ) | ||||
| { | { | ||||
| SF_INFO si; | |||||
| assert( _in == NULL ); | |||||
| /* SF_INFO si; */ | |||||
| 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; */ | |||||
| _current_read = 0; | |||||
| _length = si.frames; | |||||
| _samplerate = si.samplerate; | |||||
| _channels = si.channels; | |||||
| seek( 0 ); | |||||
| // seek( 0 ); | |||||
| return true; | return true; | ||||
| } | } | ||||
| void | void | ||||
| Audio_File_SF::close ( void ) | Audio_File_SF::close ( void ) | ||||
| { | { | ||||
| // sf_close( _in ); | |||||
| if ( _in ) | |||||
| sf_close( _in ); | |||||
| _in = NULL; | |||||
| } | } | ||||
| void | void | ||||
| @@ -36,6 +36,12 @@ public: | |||||
| static Audio_File_SF *from_file ( const char *filename ); | 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 ); | 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 ); | bool open ( void ); | ||||
| void close ( void ); | void close ( void ); | ||||
| void seek ( nframes_t offset ); | void seek ( nframes_t offset ); | ||||
| @@ -78,11 +78,6 @@ Disk_Stream::Disk_Stream ( Track_Header *th, float frame_rate, nframes_t nframes | |||||
| Disk_Stream::~Disk_Stream ( ) | 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 */ | /* it isn't safe to do all this with the RT thread running */ | ||||
| engine->lock(); | engine->lock(); | ||||
| @@ -96,6 +91,14 @@ Disk_Stream::~Disk_Stream ( ) | |||||
| engine->unlock(); | engine->unlock(); | ||||
| } | } | ||||
| /** stop the IO thread, block until it finishes. */ | |||||
| void | |||||
| Disk_Stream::shutdown ( void ) | |||||
| { | |||||
| _terminate = true; | |||||
| pthread_join( _thread, NULL ); | |||||
| } | |||||
| Audio_Track * | Audio_Track * | ||||
| Disk_Stream::track ( void ) | 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 */ | /* static wrapper */ | ||||
| void * | void * | ||||
| Disk_Stream::disk_thread ( void *arg ) | Disk_Stream::disk_thread ( void *arg ) | ||||
| @@ -94,6 +94,7 @@ public: | |||||
| /* bool seek_pending ( void ); */ | /* bool seek_pending ( void ); */ | ||||
| void run ( void ); | void run ( void ); | ||||
| void shutdown ( void ); | |||||
| virtual nframes_t process ( nframes_t nframes ) = 0; | virtual nframes_t process ( nframes_t nframes ) = 0; | ||||
| @@ -123,15 +123,66 @@ Record_DS::disk_thread ( void ) | |||||
| printf( "IO thread terminating.\n" ); | printf( "IO thread terminating.\n" ); | ||||
| delete[] cbuf; | |||||
| delete[] buf; | 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 */ | /* 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 | nframes_t | ||||
| Record_DS::process ( nframes_t nframes ) | Record_DS::process ( nframes_t nframes ) | ||||
| { | { | ||||
| if ( ! _recording ) | |||||
| return 0; | |||||
| const size_t block_size = nframes * sizeof( sample_t ); | const size_t block_size = nframes * sizeof( sample_t ); | ||||
| // printf( "process: %lu %lu %lu\n", _frame, _frame + nframes, nframes ); | // printf( "process: %lu %lu %lu\n", _frame, _frame + nframes, nframes ); | ||||
| @@ -27,6 +27,8 @@ class Audio_File; | |||||
| class Record_DS : public Disk_Stream | class Record_DS : public Disk_Stream | ||||
| { | { | ||||
| volatile bool _recording; | |||||
| Audio_File_SF *_af; /* capture file */ | Audio_File_SF *_af; /* capture file */ | ||||
| void write_block ( sample_t *buf, nframes_t nframes ); | 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 ) : | Record_DS ( Track_Header *th, float frame_rate, nframes_t nframes, int channels ) : | ||||
| Disk_Stream( th, frame_rate, nframes, 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_destroy( &_blocks ); | ||||
| sem_init( &_blocks, 0, 0 ); | sem_init( &_blocks, 0, 0 ); | ||||
| run(); | |||||
| _recording = false; | |||||
| } | } | ||||
| /* bool seek_pending ( void ); */ | /* bool seek_pending ( void ); */ | ||||
| /* void seek ( nframes_t frame ); */ | /* void seek ( nframes_t frame ); */ | ||||
| void start ( nframes_t frame ); | |||||
| void stop ( nframes_t frame ); | |||||
| nframes_t process ( nframes_t nframes ); | nframes_t process ( nframes_t nframes ); | ||||
| }; | }; | ||||
| @@ -19,6 +19,7 @@ | |||||
| #include "Track_Header.H" | #include "Track_Header.H" | ||||
| #include "Transport.H" | |||||
| #include "Playback_DS.H" | #include "Playback_DS.H" | ||||
| #include "Record_DS.H" | #include "Record_DS.H" | ||||
| @@ -59,8 +60,11 @@ Track_Header::cb_button ( Fl_Widget *w ) | |||||
| printf( "FIXME: inform mixer here\n" ); | printf( "FIXME: inform mixer here\n" ); | ||||
| if ( w == record_button ) | 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 | else | ||||
| if ( w == take_menu ) | 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 ) ); | 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 ); | 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() ); | Fl_Group::size( w(), height() ); | ||||