Try to get captures to begin and end on the proper frame.

This commit is contained in:
Jonathan Moore Liles 2008-05-01 18:35:46 -05:00
parent 68f924ab1b
commit bdd9dc56e4
8 changed files with 100 additions and 42 deletions

View File

@ -96,6 +96,46 @@ Disk_Stream::~Disk_Stream ( )
engine->unlock(); engine->unlock();
} }
/* THREAD: RT */
/** flush buffers and reset. Must only be called from the RT thread. */
void
Disk_Stream::flush ( bool is_output )
{
/* flush buffers */
for ( int i = channels(); i--; )
jack_ringbuffer_read_advance( _rb[ i ], jack_ringbuffer_read_space( _rb[ i ] ) );
/* sem_destroy( &_blocks ); */
/* if ( is_output ) */
/* sem_init( &_blocks, 0, _total_blocks ); */
/* else */
/* sem_init( &_blocks, 0, 0 ); */
if ( is_output )
{
int n;
sem_getvalue( &_blocks, &n );
n = _total_blocks - n;
while ( n-- )
sem_post( &_blocks );
}
else
{
sem_destroy( &_blocks );
sem_init( &_blocks, 0, 0 );
}
}
/** stop the IO thread, block until it finishes. */ /** stop the IO thread, block until it finishes. */
void void
Disk_Stream::shutdown ( void ) Disk_Stream::shutdown ( void )

View File

@ -71,7 +71,7 @@ protected:
void block_processed ( void ) { sem_post( &_blocks ); } void block_processed ( void ) { sem_post( &_blocks ); }
bool wait_for_block ( void ) bool wait_for_block ( void )
{ {
while ( sem_wait( &_blocks ) == EINTR ); while ( ! sem_wait( &_blocks ) && errno == EINTR );
if ( _terminate ) if ( _terminate )
return false; return false;
@ -81,6 +81,8 @@ protected:
virtual void disk_thread ( void ) = 0; virtual void disk_thread ( void ) = 0;
void flush ( bool is_output );
public: public:
/* must be set before any Disk_Streams are created */ /* must be set before any Disk_Streams are created */

View File

@ -52,23 +52,7 @@ Playback_DS::seek ( nframes_t frame )
_pending_seek = frame; _pending_seek = frame;
/* flush buffers */ flush( true );
for ( int i = channels(); i--; )
jack_ringbuffer_read_advance( _rb[ i ], jack_ringbuffer_read_space( _rb[ i ] ) );
/* dirty hack... reset the semaphore. Should we just call sem_init
* again instead? */
/* sem_init( &_blocks, 0, _total_blocks ); */
int n;
sem_getvalue( &_blocks, &n );
n = _total_blocks - n;
while ( n-- )
sem_post( &_blocks );
} }
/* THREAD: IO */ /* THREAD: IO */

View File

@ -43,7 +43,7 @@ Record_DS::write_block ( sample_t *buf, nframes_t nframes )
_th->write( buf, nframes ); _th->write( buf, nframes );
// track()->record( buf, _frame, nframes, channels() ); _frames_written += nframes;
// timeline->unlock(); // timeline->unlock();
} }
@ -52,7 +52,6 @@ Record_DS::write_block ( sample_t *buf, nframes_t nframes )
void void
Record_DS::disk_thread ( void ) Record_DS::disk_thread ( void )
{ {
printf( "IO thread running...\n" ); printf( "IO thread running...\n" );
const nframes_t nframes = _nframes * _disk_io_blocks; const nframes_t nframes = _nframes * _disk_io_blocks;
@ -134,17 +133,47 @@ Record_DS::disk_thread ( void )
printf( "IO thread terminating.\n" ); printf( "IO thread terminating.\n" );
/* flush what remains in the buffer out to disk */
{
/* use JACk sized blocks for this last bit */
const nframes_t nframes = _nframes;
const size_t block_size = _nframes * sizeof( sample_t );
while ( blocks_ready-- > 0 || ! sem_trywait( &_blocks ) && errno != EAGAIN )
{
for ( int i = channels(); i--; )
{
jack_ringbuffer_read( _rb[ i ], (char*)cbuf, block_size );
buffer_interleave_one_channel( buf, cbuf, i, channels(), nframes );
}
const nframes_t frames_remaining = (_stop_frame - _frame ) - _frames_written;
if ( frames_remaining < nframes )
{
/* this is the last block, might be partial */
write_block( buf, frames_remaining );
break;
}
else
write_block( buf, nframes );
}
}
delete[] cbuf; delete[] cbuf;
delete[] buf; delete[] buf;
} }
/** begin recording */ /** begin recording */
/* FIXME: we need to make note of the exact frame we were on when recording began */
void void
Record_DS::start ( nframes_t frame ) Record_DS::start ( nframes_t frame )
{ {
/* FIXME: flush buffers here? */
if ( _recording ) if ( _recording )
{ {
@ -152,6 +181,8 @@ Record_DS::start ( nframes_t frame )
return; return;
} }
/* FIXME: safe to do this here? */
flush( false );
_frame = frame; _frame = frame;
@ -174,25 +205,17 @@ Record_DS::stop ( nframes_t frame )
return; return;
} }
_recording = false;
/* FIXME: we may still have data in the buffers waiting to be
* written to disk... We should flush it out before stopping... */
_stop_frame = frame;
shutdown(); shutdown();
/* FIXME: flush buffers here? */ /* FIXME: flush buffers here? */
/* char *name = strdup( _af->name() ); */
/* delete _af; */
/* _af = NULL; */
/* Audio_File *af = Audio_File::from_file( name ); */
/* if ( ! af ) */
/* printf( "impossible!\n" ); */
/* new Region( af, track(), _frame ); */
/* track()->redraw(); */
_recording = false;
_th->stop( frame ); _th->stop( frame );
printf( "recording finished\n" ); printf( "recording finished\n" );

View File

@ -28,6 +28,9 @@ class Peak_Writer;
class Record_DS : public Disk_Stream class Record_DS : public Disk_Stream
{ {
nframes_t _frames_written;
volatile nframes_t _stop_frame;
volatile bool _recording; volatile bool _recording;
Audio_File_SF *_af; /* capture file */ Audio_File_SF *_af; /* capture file */
@ -44,6 +47,8 @@ public:
sem_init( &_blocks, 0, 0 ); sem_init( &_blocks, 0, 0 );
_recording = false; _recording = false;
_stop_frame = -1;
_frames_written = 0;
} }
/* bool seek_pending ( void ); */ /* bool seek_pending ( void ); */

View File

@ -947,14 +947,18 @@ Region::prepare ( void )
/** finalize region capture. Assumes that this *is* a captured region /** finalize region capture. Assumes that this *is* a captured region
and that no other regions refer to the same source */ and that no other regions refer to the same source */
bool bool
Region::finalize ( void ) Region::finalize ( nframes_t frame )
{ {
log_end(); log_end();
_clip->close(); _clip->close();
_clip->open(); _clip->open();
_range.end = _clip->length(); /* FIXME: should we attempt to truncate the file? */
_range.end = frame - _range.offset;
redraw();
return true; return true;
} }

View File

@ -204,6 +204,6 @@ public:
nframes_t read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const; nframes_t read ( sample_t *buf, nframes_t pos, nframes_t nframes, int channel ) const;
nframes_t write ( nframes_t nframes ); nframes_t write ( nframes_t nframes );
void prepare ( void ); void prepare ( void );
bool finalize ( void ); bool finalize ( nframes_t frame );
}; };

View File

@ -749,9 +749,9 @@ Track::write ( sample_t *buf, nframes_t nframes )
/* THREAD: IO */ /* THREAD: IO */
void void
Track::stop ( nframes_t nframes ) Track::stop ( nframes_t frame )
{ {
_capture->finalize(); _capture->finalize( frame );
_capture = NULL; _capture = NULL;
} }