| @@ -70,6 +70,7 @@ public: | |||||
| float frame_rate ( void ) const { return jack_get_sample_rate( _client ); } | float frame_rate ( void ) const { return jack_get_sample_rate( _client ); } | ||||
| nframes_t sample_rate ( void ) const { return _sample_rate; } | nframes_t sample_rate ( void ) const { return _sample_rate; } | ||||
| int xruns ( void ) const { return _xruns; }; | int xruns ( void ) const { return _xruns; }; | ||||
| int dropped ( void ) const { return _buffers_dropped; } | |||||
| float cpu_load ( void ) const { return jack_cpu_load( _client ); } | float cpu_load ( void ) const { return jack_cpu_load( _client ); } | ||||
| }; | }; | ||||
| @@ -189,8 +189,12 @@ Playback_DS::disk_thread ( void ) | |||||
| buffer_deinterleave_one_channel( (sample_t*)rbd[ 1 ].buf, buf + f, i, channels(), nframes - f ); | buffer_deinterleave_one_channel( (sample_t*)rbd[ 1 ].buf, buf + f, i, channels(), nframes - f ); | ||||
| } | } | ||||
| else | else | ||||
| { | |||||
| ++_xruns; | |||||
| printf( "programming error: expected more space in ringbuffer\n" ); | printf( "programming error: expected more space in ringbuffer\n" ); | ||||
| } | |||||
| /* buffer_deinterleave_one_channel( (sample_t*)rbd.buf, buf, i, channels(), _nframes ); */ | /* buffer_deinterleave_one_channel( (sample_t*)rbd.buf, buf, i, channels(), _nframes ); */ | ||||
| /* jack_ringbuffer_write( _rb[ i ], (char*)cbuf, block_size ); */ | /* jack_ringbuffer_write( _rb[ i ], (char*)cbuf, block_size ); */ | ||||
| @@ -223,6 +227,7 @@ Playback_DS::process ( nframes_t nframes ) | |||||
| if ( jack_ringbuffer_read( _rb[ i ], (char*)buf, block_size ) < block_size ) | if ( jack_ringbuffer_read( _rb[ i ], (char*)buf, block_size ) < block_size ) | ||||
| { | { | ||||
| ++_xruns; | |||||
| printf( "RT: buffer underrun (disk can't keep up).\n" ); | printf( "RT: buffer underrun (disk can't keep up).\n" ); | ||||
| memset( buf, 0, block_size ); | memset( buf, 0, block_size ); | ||||
| /* FIXME: we need to resync somehow */ | /* FIXME: we need to resync somehow */ | ||||
| @@ -59,7 +59,7 @@ Record_DS::disk_thread ( void ) | |||||
| /* buffer to hold the interleaved data returned by the track reader */ | /* buffer to hold the interleaved data returned by the track reader */ | ||||
| sample_t *buf = new sample_t[ nframes * channels() ]; | sample_t *buf = new sample_t[ nframes * channels() ]; | ||||
| sample_t *cbuf = new sample_t[ nframes ]; | |||||
| sample_t *cbuf = new sample_t[ nframes ]; | |||||
| const size_t block_size = nframes * sizeof( sample_t ); | const size_t block_size = nframes * sizeof( sample_t ); | ||||
| @@ -80,17 +80,14 @@ Record_DS::disk_thread ( void ) | |||||
| /* pull data from the per-channel ringbuffers and interlace it */ | /* pull data from the per-channel ringbuffers and interlace it */ | ||||
| for ( int i = channels(); i--; ) | for ( int i = channels(); i--; ) | ||||
| { | { | ||||
| /* while ( jack_ringbuffer_read_space( _rb[ i ] ) < block_size ) */ | |||||
| /* { */ | |||||
| /* printf( "IO: disk buffer underrun!\n" ); */ | |||||
| /* /\* FIXME: is this *really* the right thing to do? *\/ */ | |||||
| /* usleep( 2000 ); */ | |||||
| /* } */ | |||||
| /* FIXME: avoid this copy */ | /* FIXME: avoid this copy */ | ||||
| if ( jack_ringbuffer_read( _rb[ i ], (char*)cbuf, block_size ) < block_size ) | |||||
| { | |||||
| ++_xruns; | |||||
| jack_ringbuffer_read( _rb[ i ], (char*)cbuf, block_size ); | |||||
| /* FIXME: what now? */ | |||||
| printf( "Record_DS: underrun!\n" ); | |||||
| } | |||||
| buffer_interleave_one_channel( buf, cbuf, i, channels(), nframes ); | buffer_interleave_one_channel( buf, cbuf, i, channels(), nframes ); | ||||
| @@ -221,6 +218,7 @@ Record_DS::process ( nframes_t nframes ) | |||||
| if ( jack_ringbuffer_write( _rb[ i ], (char*)buf, block_size ) < block_size ) | if ( jack_ringbuffer_write( _rb[ i ], (char*)buf, block_size ) < block_size ) | ||||
| { | { | ||||
| ++_xruns; | |||||
| printf( "RT: buffer overrun (disk can't keep up).\n" ); | printf( "RT: buffer overrun (disk can't keep up).\n" ); | ||||
| memset( buf, 0, block_size ); | memset( buf, 0, block_size ); | ||||
| /* FIXME: we need to resync somehow */ | /* FIXME: we need to resync somehow */ | ||||
| @@ -156,7 +156,9 @@ Loggable::compact();} | |||||
| label {&Quit} | label {&Quit} | ||||
| callback {save(); | callback {save(); | ||||
| exit( 0 );} | |||||
| printf( "dropped %d buffers\\n", engine->dropped() ); | |||||
| exit( 0 );} selected | |||||
| xywh {40 40 40 25} shortcut 0x40071 | xywh {40 40 40 25} shortcut 0x40071 | ||||
| } | } | ||||
| } | } | ||||
| @@ -245,7 +247,7 @@ exit( 0 );} | |||||
| } | } | ||||
| } | } | ||||
| Submenu timeline_menu { | Submenu timeline_menu { | ||||
| label {&Timeline} open | |||||
| label {&Timeline} | |||||
| xywh {0 0 74 25} | xywh {0 0 74 25} | ||||
| } { | } { | ||||
| MenuItem {} { | MenuItem {} { | ||||
| @@ -255,7 +257,7 @@ exit( 0 );} | |||||
| } | } | ||||
| MenuItem {} { | MenuItem {} { | ||||
| label {&Center Playhead} | label {&Center Playhead} | ||||
| callback {Timeline::center_playhead = menu_picked_value( o );} selected | |||||
| callback {Timeline::center_playhead = menu_picked_value( o );} | |||||
| xywh {30 30 40 25} type Toggle value 1 | xywh {30 30 40 25} type Toggle value 1 | ||||
| } | } | ||||
| Submenu {} { | Submenu {} { | ||||
| @@ -552,6 +554,14 @@ update_progress( playback_buffer_progress, pbp, timeline->total_output_buffer_pe | |||||
| update_progress( cpu_load_progress, clp, engine->cpu_load() ); | update_progress( cpu_load_progress, clp, engine->cpu_load() ); | ||||
| if ( timeline->total_capture_xruns() ) | |||||
| capture_buffer_progress->selection_color( FL_RED ); | |||||
| if ( timeline->total_playback_xruns() ) | |||||
| playback_buffer_progress->selection_color( FL_RED ); | |||||
| xruns_output->value( engine->xruns() );} {} | xruns_output->value( engine->xruns() );} {} | ||||
| } | } | ||||
| Function {update_cb( void *v )} {open return_type {static void} | Function {update_cb( void *v )} {open return_type {static void} | ||||
| @@ -1251,3 +1251,35 @@ Timeline::total_output_buffer_percent ( void ) | |||||
| return r / cnt; | return r / cnt; | ||||
| } | } | ||||
| int | |||||
| Timeline::total_playback_xruns ( void ) | |||||
| { | |||||
| int r = 0; | |||||
| for ( int i = tracks->children(); i-- ; ) | |||||
| { | |||||
| Track *t = (Track*)tracks->child( i ); | |||||
| if ( t->playback_ds ) | |||||
| r += t->playback_ds->xruns(); | |||||
| } | |||||
| return r; | |||||
| } | |||||
| int | |||||
| Timeline::total_capture_xruns ( void ) | |||||
| { | |||||
| int r = 0; | |||||
| for ( int i = tracks->children(); i-- ; ) | |||||
| { | |||||
| Track *t = (Track*)tracks->child( i ); | |||||
| if ( t->record_ds ) | |||||
| r += t->record_ds->xruns(); | |||||
| } | |||||
| return r; | |||||
| } | |||||
| @@ -172,6 +172,8 @@ public: | |||||
| int total_input_buffer_percent ( void ); | int total_input_buffer_percent ( void ); | ||||
| int total_output_buffer_percent ( void ); | int total_output_buffer_percent ( void ); | ||||
| int total_playback_xruns ( void ); | |||||
| int total_capture_xruns ( void ); | |||||
| bool record ( void ); | bool record ( void ); | ||||
| void stop ( void ); | void stop ( void ); | ||||