Browse Source

Respond appropriately to changes in JACK buffer size.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
48d7f61f8a
12 changed files with 101 additions and 26 deletions
  1. +45
    -20
      Timeline/Disk_Stream.C
  2. +8
    -2
      Timeline/Disk_Stream.H
  3. +17
    -0
      Timeline/Engine.C
  4. +2
    -0
      Timeline/Engine.H
  5. +1
    -2
      Timeline/Playback_DS.C
  6. +2
    -0
      Timeline/Playback_DS.H
  7. +1
    -1
      Timeline/Record_DS.C
  8. +2
    -0
      Timeline/Record_DS.H
  9. +12
    -0
      Timeline/Timeline.C
  10. +1
    -0
      Timeline/Timeline.H
  11. +9
    -1
      Timeline/Track.C
  12. +1
    -0
      Timeline/Track.H

+ 45
- 20
Timeline/Disk_Stream.C View File

@@ -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();
}
}




+ 8
- 2
Timeline/Disk_Stream.H View File

@@ -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 ); */


+ 17
- 0
Timeline/Engine.C View File

@@ -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)? */


+ 2
- 0
Timeline/Engine.H View File

@@ -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 );


+ 1
- 2
Timeline/Playback_DS.C View File

@@ -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 */


+ 2
- 0
Timeline/Playback_DS.H View File

@@ -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 ) :


+ 1
- 1
Timeline/Record_DS.C View File

@@ -199,7 +199,7 @@ Record_DS::start ( nframes_t frame )
}

/* FIXME: safe to do this here? */
flush( false );
flush();

_frame = frame;



+ 2
- 0
Timeline/Record_DS.H View File

@@ -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 ) :


+ 12
- 0
Timeline/Timeline.C View File

@@ -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 )


+ 1
- 0
Timeline/Timeline.H View File

@@ -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 );


+ 9
- 1
Timeline/Track.C View File

@@ -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? */


+ 1
- 0
Timeline/Track.H View File

@@ -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…
Cancel
Save