Try to get captures to begin and end on the proper frame.
This commit is contained in:
parent
68f924ab1b
commit
bdd9dc56e4
|
@ -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 )
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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" );
|
||||||
|
|
|
@ -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 ); */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue