@@ -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; | |||
} | |||
@@ -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 | |||
@@ -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 ); | |||
@@ -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; | |||
} |
@@ -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 ); | |||
_thread = 0; | |||
/* 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 ); | |||
_terminate = false; | |||
_thread = 0; | |||
} | |||
Track * | |||
@@ -196,6 +196,8 @@ Playback_DS::disk_thread ( void ) | |||
#ifndef AVOID_UNNECESSARY_COPYING | |||
delete[] cbuf; | |||
#endif | |||
_terminate = false; | |||
} | |||
/* THREAD: RT */ | |||
@@ -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" ); | |||
} | |||
@@ -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 ); | |||
@@ -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(); | |||
@@ -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 <stdio.h> | |||
/* THREAD: IO */ | |||
void | |||
Track::stop ( nframes_t frame ) | |||
Track::finalize ( Capture *c, nframes_t frame ) | |||
{ | |||
_capture->finalize( frame ); | |||
_capture = NULL; | |||
_capture_af->finalize(); | |||
c->region->finalize( frame ); | |||
c->audio_file->finalize(); | |||
delete _capture_af; | |||
_capture_af = NULL; | |||
delete c->audio_file; | |||
} |
@@ -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; | |||
@@ -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 ); | |||
}; |