diff --git a/Timeline/Audio_Region.C b/Timeline/Audio_Region.C index c398799..0a9aae8 100644 --- a/Timeline/Audio_Region.C +++ b/Timeline/Audio_Region.C @@ -503,7 +503,7 @@ Audio_Region::draw_box( void ) color = fl_color_average( color, sequence()->color(), 0.75f ); - if ( this == ((Audio_Sequence*)sequence())->capture() ) + if ( this == ((Audio_Sequence*)sequence())->capture_region() ) { color = FL_RED; } diff --git a/Timeline/Audio_Sequence.C b/Timeline/Audio_Sequence.C index 0207be7..c10c1af 100644 --- a/Timeline/Audio_Sequence.C +++ b/Timeline/Audio_Sequence.C @@ -54,9 +54,9 @@ Audio_Sequence::~Audio_Sequence ( ) const Audio_Region * -Audio_Sequence::capture ( void ) const +Audio_Sequence::capture_region ( void ) const { - return track()->capture(); + return track()->capture_region(); } void diff --git a/Timeline/Audio_Sequence.H b/Timeline/Audio_Sequence.H index 4b8eb88..ff11f3c 100644 --- a/Timeline/Audio_Sequence.H +++ b/Timeline/Audio_Sequence.H @@ -66,7 +66,7 @@ public: void dump ( void ); void remove_selected ( void ); - const Audio_Region *capture ( void ) const; + const Audio_Region *capture_region ( void ) const; nframes_t play ( sample_t *buf, nframes_t frame, nframes_t nframes, int channels ); diff --git a/Timeline/Engine/Audio_Region.C b/Timeline/Engine/Audio_Region.C index 94a19b0..f83741c 100644 --- a/Timeline/Engine/Audio_Region.C +++ b/Timeline/Engine/Audio_Region.C @@ -209,6 +209,7 @@ Audio_Region::write ( nframes_t nframes ) return nframes; } +/* THREAD: IO */ /** finalize region capture. Assumes that this *is* a captured region and that no other regions refer to the same source */ bool @@ -222,8 +223,10 @@ Audio_Region::finalize ( nframes_t frame ) _clip->open(); /* FIXME: should we attempt to truncate the file? */ - + Fl::lock(); redraw(); + Fl::awake(); + Fl::unlock(); return true; } diff --git a/Timeline/Engine/Disk_Stream.C b/Timeline/Engine/Disk_Stream.C index 0d7e8ef..f6afc02 100644 --- a/Timeline/Engine/Disk_Stream.C +++ b/Timeline/Engine/Disk_Stream.C @@ -122,7 +122,7 @@ Disk_Stream::base_flush ( bool is_output ) } -/** stop the IO thread, block until it finishes. */ +/** stop the IO thread. */ void Disk_Stream::shutdown ( void ) { @@ -132,11 +132,15 @@ Disk_Stream::shutdown ( void ) block_processed(); if ( _thread ) - pthread_join( _thread, NULL ); + pthread_detach( _thread ); + + /* we must block until the thread returns, because it might + * still have data left to process in its buffers--and we + * don't want to delete any of the datastructures it's using + * until it finishes with them. */ +// pthread_join( _thread, NULL ); _thread = 0; - - _terminate = false; } Track * diff --git a/Timeline/Engine/Playback_DS.C b/Timeline/Engine/Playback_DS.C index 9ab8559..49283c8 100644 --- a/Timeline/Engine/Playback_DS.C +++ b/Timeline/Engine/Playback_DS.C @@ -196,6 +196,8 @@ Playback_DS::disk_thread ( void ) #ifndef AVOID_UNNECESSARY_COPYING delete[] cbuf; #endif + + _terminate = false; } /* THREAD: RT */ diff --git a/Timeline/Engine/Record_DS.C b/Timeline/Engine/Record_DS.C index 8814e7d..885b267 100644 --- a/Timeline/Engine/Record_DS.C +++ b/Timeline/Engine/Record_DS.C @@ -31,6 +31,15 @@ #include "util/debug.h" +const Audio_Region * +Record_DS::capture_region ( void ) const +{ + if ( _capture ) + return _capture->region; + else + return NULL; +} + /* THREAD: IO */ /** write /nframes/ from buf to the capture file of the attached track */ void @@ -43,7 +52,7 @@ Record_DS::write_block ( sample_t *buf, nframes_t nframes ) // timeline->wrlock(); - track()->write( buf, nframes ); + track()->write( _capture, buf, nframes ); _frames_written += nframes; @@ -181,6 +190,14 @@ Record_DS::disk_thread ( void ) #ifndef AVOID_UNNECESSARY_COPYING delete[] cbuf; #endif + + /* now finalize the recording */ + track()->finalize( _capture, _stop_frame ); + + delete _capture; + _capture = NULL; + + _terminate = false; } @@ -200,7 +217,9 @@ Record_DS::start ( nframes_t frame ) _frame = frame; - track()->record( frame ); + _capture = new Track::Capture; + + track()->record( _capture, frame ); run(); @@ -224,8 +243,6 @@ Record_DS::stop ( nframes_t frame ) shutdown(); - track()->stop( frame ); - DMESSAGE( "recording finished" ); } diff --git a/Timeline/Engine/Record_DS.H b/Timeline/Engine/Record_DS.H index fa7d4dc..e83181f 100644 --- a/Timeline/Engine/Record_DS.H +++ b/Timeline/Engine/Record_DS.H @@ -24,6 +24,7 @@ #include "Audio_File_SF.H" class Audio_File; class Peak_Writer; +class Track::Capture; class Record_DS : public Disk_Stream { @@ -32,6 +33,7 @@ class Record_DS : public Disk_Stream Record_DS ( const Record_DS &rhs ); Record_DS & operator= ( const Record_DS &rhs ); + Track::Capture *_capture; nframes_t _frames_written; volatile nframes_t _stop_frame; @@ -53,6 +55,7 @@ public: sem_destroy( &_blocks ); sem_init( &_blocks, 0, 0 ); + _capture = NULL; _recording = false; _stop_frame = -1; _frames_written = 0; @@ -60,6 +63,7 @@ public: /* bool seek_pending ( void ); */ /* void seek ( nframes_t frame ); */ + const Audio_Region * capture_region ( void ) const; void start ( nframes_t frame ); void stop ( nframes_t frame ); diff --git a/Timeline/Engine/Timeline.C b/Timeline/Engine/Timeline.C index 96d8e40..490dded 100644 --- a/Timeline/Engine/Timeline.C +++ b/Timeline/Engine/Timeline.C @@ -34,12 +34,14 @@ Timeline::record ( void ) Loggable::block_start(); + nframes_t frame = transport->frame; + for ( int i = tracks->children(); i-- ; ) { Track *t = (Track*)tracks->child( i ); if ( t->armed() && t->record_ds ) - t->record_ds->start( transport->frame ); + t->record_ds->start( frame ); } deactivate(); diff --git a/Timeline/Engine/Track.C b/Timeline/Engine/Track.C index ca046fe..99b7479 100644 --- a/Timeline/Engine/Track.C +++ b/Timeline/Engine/Track.C @@ -29,6 +29,15 @@ /* Engine */ /**********/ +const Audio_Region * +Track::capture_region ( void ) const +{ + if ( record_ds ) + return record_ds->capture_region(); + else + return NULL; +} + void Track::update_port_names ( void ) { @@ -209,57 +218,47 @@ uuid ( void ) } + /* THREAD: IO */ /** create capture region and prepare to record */ void -Track::record ( nframes_t frame ) +Track::record ( Capture *c, nframes_t frame ) { - assert( ! _capture ); - assert( ! _capture_af ); - char pat[256]; snprintf( pat, sizeof( pat ), "%s-%llu", name(), uuid() ); + c->audio_file = Audio_File_SF::create( pat, engine->sample_rate(), input.size(), Track::capture_format ); - _capture_af = Audio_File_SF::create( pat, engine->sample_rate(), input.size(), Track::capture_format ); - - if ( ! _capture_af ) - { - /* ERROR */ - - } + if ( ! c->audio_file ) + FATAL( "Could not create file for new capture!" ); /* open it again for reading in the GUI thread */ - Audio_File *af = Audio_File::from_file( _capture_af->name() ); + Audio_File *af = Audio_File::from_file( c->audio_file->name() ); - _capture = new Audio_Region( af, sequence(), frame ); + c->region = new Audio_Region( af, sequence(), frame ); - _capture->prepare(); + c->region->prepare(); } /* THREAD: IO */ /** write a block to the (already opened) capture file */ void -Track::write ( sample_t *buf, nframes_t nframes ) +Track::write ( Capture *c, sample_t *buf, nframes_t nframes ) { - nframes_t l = _capture_af->write( buf, nframes ); + nframes_t l = c->audio_file->write( buf, nframes ); - _capture->write( l ); + c->region->write( l ); } #include /* THREAD: IO */ void -Track::stop ( nframes_t frame ) +Track::finalize ( Capture *c, nframes_t frame ) { - _capture->finalize( frame ); + c->region->finalize( frame ); + c->audio_file->finalize(); - _capture = NULL; - - _capture_af->finalize(); - - delete _capture_af; - _capture_af = NULL; + delete c->audio_file; } diff --git a/Timeline/Track.C b/Timeline/Track.C index 6aee411..0cef2df 100644 --- a/Timeline/Track.C +++ b/Timeline/Track.C @@ -111,8 +111,6 @@ Track::cb_button ( Fl_Widget *w ) void Track::init ( void ) { - _capture = NULL; - _capture_af = NULL; _sequence = NULL; _name = NULL; _selected = false; diff --git a/Timeline/Track.H b/Timeline/Track.H index 26b472d..8f2397d 100644 --- a/Timeline/Track.H +++ b/Timeline/Track.H @@ -69,6 +69,12 @@ public: static const char *capture_format; + struct Capture + { + Audio_File *audio_file; + Audio_Region *region; + }; + private: static int _soloing; @@ -85,9 +91,6 @@ private: Audio_Sequence *_sequence; - Audio_Region *_capture; /* capture region */ - Audio_File *_capture_af; /* capture write source */ - bool configure_outputs ( int n ); bool configure_inputs ( int n ); @@ -264,14 +267,15 @@ public: int handle ( int m ); - const Audio_Region *capture ( void ) const { return _capture; } - /* Engine */ + const Audio_Region *capture_region ( void ) const; + void resize_buffers ( nframes_t nframes ); nframes_t process ( nframes_t nframes ); void seek ( nframes_t frame ); - void record ( nframes_t nframes ); - void write ( sample_t *buf, nframes_t nframes ); - void stop ( nframes_t nframes ); + + void record ( Capture *c, nframes_t frame ); + void write ( Capture *c, sample_t *buf, nframes_t nframes ); + void finalize ( Capture *c, nframes_t frame ); };