Respond appropriately to changes in JACK buffer size.
This commit is contained in:
parent
97f0283780
commit
48d7f61f8a
|
@ -52,7 +52,6 @@ size_t Disk_Stream::disk_io_kbytes = 256;
|
|||
|
||||
Disk_Stream::Disk_Stream ( Track *track, float frame_rate, nframes_t nframes, int channels ) : _track( track )
|
||||
{
|
||||
|
||||
assert( channels );
|
||||
|
||||
_frame = 0;
|
||||
|
@ -60,20 +59,9 @@ Disk_Stream::Disk_Stream ( Track *track, float frame_rate, nframes_t nframes, in
|
|||
_terminate = false;
|
||||
_pending_seek = -1;
|
||||
_xruns = 0;
|
||||
_frame_rate = frame_rate;
|
||||
|
||||
_total_blocks = frame_rate * seconds_to_buffer / nframes;
|
||||
|
||||
_nframes = nframes;
|
||||
|
||||
size_t bufsize = _total_blocks * nframes * sizeof( sample_t );
|
||||
|
||||
if ( disk_io_kbytes )
|
||||
_disk_io_blocks = ( bufsize * channels ) / ( disk_io_kbytes * 1024 );
|
||||
else
|
||||
_disk_io_blocks = 1;
|
||||
|
||||
for ( int i = channels; i--; )
|
||||
_rb.push_back( jack_ringbuffer_create( bufsize ) );
|
||||
_resize_buffers( nframes, channels );
|
||||
|
||||
sem_init( &_blocks, 0, _total_blocks );
|
||||
}
|
||||
|
@ -97,14 +85,13 @@ Disk_Stream::~Disk_Stream ( )
|
|||
/* THREAD: RT */
|
||||
/** flush buffers and reset. Must only be called from the RT thread. */
|
||||
void
|
||||
Disk_Stream::flush ( bool is_output )
|
||||
Disk_Stream::base_flush ( bool is_output )
|
||||
{
|
||||
|
||||
/* flush buffers */
|
||||
for ( int i = channels(); i--; )
|
||||
for ( int i = _rb.size(); i--; )
|
||||
jack_ringbuffer_read_advance( _rb[ i ], jack_ringbuffer_read_space( _rb[ i ] ) );
|
||||
|
||||
|
||||
/* sem_destroy( &_blocks ); */
|
||||
|
||||
/* if ( is_output ) */
|
||||
|
@ -114,7 +101,6 @@ Disk_Stream::flush ( bool is_output )
|
|||
|
||||
if ( is_output )
|
||||
{
|
||||
|
||||
int n;
|
||||
sem_getvalue( &_blocks, &n );
|
||||
|
||||
|
@ -145,6 +131,7 @@ Disk_Stream::shutdown ( void )
|
|||
if ( _thread )
|
||||
pthread_join( _thread, NULL );
|
||||
|
||||
_thread = 0;
|
||||
_terminate = false;
|
||||
}
|
||||
|
||||
|
@ -168,12 +155,50 @@ Disk_Stream::run ( void )
|
|||
FATAL( "Could not create IO thread!" );
|
||||
}
|
||||
|
||||
void
|
||||
Disk_Stream::_resize_buffers ( nframes_t nframes, int channels )
|
||||
{
|
||||
for ( int i = _rb.size(); i--; )
|
||||
jack_ringbuffer_free( _rb[ i ] );
|
||||
|
||||
_rb.clear();
|
||||
|
||||
_nframes = nframes;
|
||||
|
||||
_total_blocks = _frame_rate * seconds_to_buffer / nframes;
|
||||
|
||||
size_t bufsize = _total_blocks * nframes * sizeof( sample_t );
|
||||
|
||||
if ( disk_io_kbytes )
|
||||
_disk_io_blocks = ( bufsize * channels ) / ( disk_io_kbytes * 1024 );
|
||||
else
|
||||
_disk_io_blocks = 1;
|
||||
|
||||
for ( int i = channels; i--; )
|
||||
_rb.push_back( jack_ringbuffer_create( bufsize ) );
|
||||
}
|
||||
|
||||
/* THREAD: RT (non-RT) */
|
||||
/* to be called when the JACK buffer size changes. */
|
||||
void
|
||||
Disk_Stream::resize ( nframes_t nframes )
|
||||
Disk_Stream::resize_buffers ( nframes_t nframes )
|
||||
{
|
||||
if ( nframes != _nframes )
|
||||
/* FIXME: to something here! */;
|
||||
{
|
||||
DMESSAGE( "resizing buffers" );
|
||||
|
||||
const bool was_running = _thread;
|
||||
|
||||
if ( was_running )
|
||||
shutdown();
|
||||
|
||||
flush();
|
||||
|
||||
_resize_buffers( nframes, channels() );
|
||||
|
||||
if ( was_running )
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ protected:
|
|||
int _total_blocks; /* total number of blocks that we can buffer */
|
||||
int _disk_io_blocks; /* the number of blocks to read/write to/from disk at once */
|
||||
|
||||
|
||||
nframes_t _frame_rate; /* used for buffer size calculations */
|
||||
|
||||
volatile nframes_t _pending_seek; /* absolute transport position to seek to */
|
||||
volatile int _terminate;
|
||||
|
||||
|
@ -71,6 +74,8 @@ protected:
|
|||
|
||||
static void *disk_thread ( void *arg );
|
||||
|
||||
void _resize_buffers ( nframes_t nframes, int channels );
|
||||
|
||||
protected:
|
||||
|
||||
void block_processed ( void ) { sem_post( &_blocks ); }
|
||||
|
@ -86,7 +91,8 @@ protected:
|
|||
|
||||
virtual void disk_thread ( void ) = 0;
|
||||
|
||||
void flush ( bool is_output );
|
||||
void base_flush ( bool is_output );
|
||||
virtual void flush ( void ) = 0;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -100,7 +106,7 @@ public:
|
|||
|
||||
virtual ~Disk_Stream ( );
|
||||
|
||||
void resize ( nframes_t nframes );
|
||||
void resize_buffers ( nframes_t nframes );
|
||||
|
||||
/* void seek ( nframes_t frame ); */
|
||||
/* bool seek_pending ( void ); */
|
||||
|
|
|
@ -70,6 +70,12 @@ Engine::freewheel ( int starting, void *arg )
|
|||
((Engine*)arg)->freewheel( starting );
|
||||
}
|
||||
|
||||
int
|
||||
Engine::buffer_size ( nframes_t nframes, void *arg )
|
||||
{
|
||||
return ((Engine*)arg)->buffer_size( nframes );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
|
@ -101,6 +107,16 @@ Engine::freewheel ( bool starting )
|
|||
DMESSAGE( "leaving freewheeling mode" );
|
||||
}
|
||||
|
||||
/* THREAD: RT (non-RT) */
|
||||
int
|
||||
Engine::buffer_size ( nframes_t nframes )
|
||||
{
|
||||
/* TODO: inform all disktreams the the buffer size has changed */
|
||||
timeline->resize_buffers( nframes );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* THREAD: RT */
|
||||
/** This is the jack slow-sync callback. */
|
||||
int
|
||||
|
@ -232,6 +248,7 @@ Engine::init ( void )
|
|||
set_callback( process );
|
||||
set_callback( xrun );
|
||||
set_callback( freewheel );
|
||||
set_callback( buffer_size );
|
||||
|
||||
/* FIXME: should we wait to register this until after the project
|
||||
has been loaded (and we have disk threads running)? */
|
||||
|
|
|
@ -55,6 +55,8 @@ class Engine : public Mutex
|
|||
void timebase ( jack_transport_state_t state, jack_nframes_t nframes, jack_position_t *pos, int new_pos );
|
||||
static void freewheel ( int yes, void *arg );
|
||||
void freewheel ( bool yes );
|
||||
static int buffer_size ( nframes_t nframes, void *arg );
|
||||
int buffer_size ( nframes_t nframes );
|
||||
|
||||
Engine ( const Engine &rhs );
|
||||
Engine & operator = ( const Engine &rhs );
|
||||
|
|
|
@ -54,7 +54,7 @@ Playback_DS::seek ( nframes_t frame )
|
|||
|
||||
_pending_seek = frame;
|
||||
|
||||
flush( true );
|
||||
flush();
|
||||
}
|
||||
|
||||
/* THREAD: IO */
|
||||
|
@ -93,7 +93,6 @@ Playback_DS::read_block ( sample_t *buf, nframes_t nframes )
|
|||
void
|
||||
Playback_DS::disk_thread ( void )
|
||||
{
|
||||
|
||||
DMESSAGE( "playback thread running" );
|
||||
|
||||
/* buffer to hold the interleaved data returned by the track reader */
|
||||
|
|
|
@ -25,6 +25,8 @@ class Playback_DS : public Disk_Stream
|
|||
void read_block ( sample_t *buf, nframes_t nframes );
|
||||
void disk_thread ( void );
|
||||
|
||||
void flush ( void ) { base_flush( true ); }
|
||||
|
||||
public:
|
||||
|
||||
Playback_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) :
|
||||
|
|
|
@ -199,7 +199,7 @@ Record_DS::start ( nframes_t frame )
|
|||
}
|
||||
|
||||
/* FIXME: safe to do this here? */
|
||||
flush( false );
|
||||
flush();
|
||||
|
||||
_frame = frame;
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ class Record_DS : public Disk_Stream
|
|||
void write_block ( sample_t *buf, nframes_t nframes );
|
||||
void disk_thread ( void );
|
||||
|
||||
void flush ( void ) { base_flush( false ); }
|
||||
|
||||
public:
|
||||
|
||||
Record_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) :
|
||||
|
|
|
@ -1233,6 +1233,18 @@ Timeline::seek ( nframes_t frame )
|
|||
}
|
||||
}
|
||||
|
||||
/* THREAD: RT (non-RT) */
|
||||
void
|
||||
Timeline::resize_buffers ( nframes_t nframes )
|
||||
{
|
||||
for ( int i = tracks->children(); i-- ; )
|
||||
{
|
||||
Track *t = (Track*)tracks->child( i );
|
||||
|
||||
t->resize_buffers( nframes );
|
||||
}
|
||||
}
|
||||
|
||||
/* THREAD: RT */
|
||||
int
|
||||
Timeline::seek_pending ( void )
|
||||
|
|
|
@ -210,6 +210,7 @@ private:
|
|||
char * get_unique_track_name ( const char *name );
|
||||
|
||||
/* Engine */
|
||||
void resize_buffers ( nframes_t nframes );
|
||||
nframes_t process ( nframes_t nframes );
|
||||
void seek ( nframes_t frame );
|
||||
int seek_pending ( void );
|
||||
|
|
|
@ -745,7 +745,15 @@ Track::seek ( nframes_t frame )
|
|||
return playback_ds->seek( frame );
|
||||
}
|
||||
|
||||
|
||||
/* THREAD: RT (non-RT) */
|
||||
void
|
||||
Track::resize_buffers ( nframes_t nframes )
|
||||
{
|
||||
if ( record_ds )
|
||||
record_ds->resize_buffers( nframes );
|
||||
if ( playback_ds )
|
||||
playback_ds->resize_buffers( nframes );
|
||||
}
|
||||
|
||||
/* FIXME: what about theading issues with this region/audiofile being
|
||||
accessible from the UI thread? Need locking? */
|
||||
|
|
|
@ -265,6 +265,7 @@ public:
|
|||
const Audio_Region *capture ( void ) const { return _capture; }
|
||||
|
||||
/* Engine */
|
||||
void resize_buffers ( nframes_t nframes );
|
||||
nframes_t process ( nframes_t nframes );
|
||||
void seek ( nframes_t frame );
|
||||
void record ( nframes_t nframes );
|
||||
|
|
Loading…
Reference in New Issue