Timeline: Add option for per-track delay-free playback latency compensation. Disabled by default.
This commit is contained in:
parent
795249a612
commit
eb482d3a36
|
@ -66,9 +66,9 @@ Playback_DS::seek ( nframes_t frame )
|
|||
/** set the playback delay to /frames/ frames. This be called prior to
|
||||
a seek. */
|
||||
void
|
||||
Playback_DS::delay ( nframes_t frames )
|
||||
Playback_DS::undelay ( nframes_t delay )
|
||||
{
|
||||
_delay = frames;
|
||||
_undelay = delay;
|
||||
}
|
||||
|
||||
/** read /nframes/ from the attached track into /buf/ */
|
||||
|
@ -94,13 +94,8 @@ Playback_DS::read_block ( sample_t *buf, nframes_t nframes )
|
|||
|
||||
if ( sequence() )
|
||||
{
|
||||
/* FIXME: how does this work if _delay is not a multiple of bufsize? */
|
||||
|
||||
if ( _frame >= _delay )
|
||||
{
|
||||
if ( ! sequence()->play( buf, _frame - _delay, nframes, channels() ) )
|
||||
if ( ! sequence()->play( buf, _frame + _undelay, nframes, channels() ) )
|
||||
WARNING( "Programming error?" );
|
||||
}
|
||||
|
||||
_frame += nframes;
|
||||
}
|
||||
|
|
|
@ -27,14 +27,15 @@ class Playback_DS : public Disk_Stream
|
|||
|
||||
void flush ( void ) { base_flush( true ); }
|
||||
|
||||
volatile nframes_t _delay; /* number of frames this diskstream should be delayed by */
|
||||
volatile nframes_t _undelay; /* number of frames this diskstream
|
||||
* should be undelayed by */
|
||||
|
||||
public:
|
||||
|
||||
Playback_DS ( Track *th, float frame_rate, nframes_t nframes, int channels ) :
|
||||
Disk_Stream( th, frame_rate, nframes, channels )
|
||||
{
|
||||
_delay = 0;
|
||||
_undelay = 0;
|
||||
|
||||
run();
|
||||
}
|
||||
|
@ -45,6 +46,6 @@ public:
|
|||
void seek ( nframes_t frame );
|
||||
nframes_t process ( nframes_t nframes );
|
||||
|
||||
void delay ( nframes_t v );
|
||||
void undelay ( nframes_t v );
|
||||
|
||||
};
|
||||
|
|
|
@ -234,17 +234,19 @@ Track::seek ( nframes_t frame )
|
|||
{
|
||||
THREAD_ASSERT( RT );
|
||||
|
||||
compute_latency_compensation();
|
||||
|
||||
if ( playback_ds )
|
||||
return playback_ds->seek( frame );
|
||||
}
|
||||
|
||||
void
|
||||
Track::delay ( nframes_t frames )
|
||||
Track::undelay ( nframes_t nframes )
|
||||
{
|
||||
// THREAD_ASSERT( RT );
|
||||
|
||||
if ( playback_ds )
|
||||
playback_ds->delay( frames );
|
||||
playback_ds->undelay( nframes );
|
||||
}
|
||||
|
||||
/* THREAD: RT (non-RT) */
|
||||
|
@ -360,3 +362,21 @@ Track::finalize ( Capture *c, nframes_t frame )
|
|||
|
||||
timeline->unlock();
|
||||
}
|
||||
|
||||
void
|
||||
Track::compute_latency_compensation ( void )
|
||||
{
|
||||
if ( Timeline::playback_latency_compensation && output.size() )
|
||||
{
|
||||
nframes_t min,max;
|
||||
output[0].get_latency( JACK::Port::Output, &min, &max );
|
||||
|
||||
DMESSAGE( "Track %s, setting undelay to %lu", name(), (unsigned long)min);
|
||||
|
||||
undelay( min );
|
||||
}
|
||||
else
|
||||
{
|
||||
undelay( 0 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -325,6 +325,11 @@ pi.run();}
|
|||
label {Capture Format} open
|
||||
xywh {25 25 74 25}
|
||||
} {}
|
||||
MenuItem {} {
|
||||
label {Playback Latency Compensation}
|
||||
callback {Timeline::playback_latency_compensation = menu_picked_value( o );} selected
|
||||
xywh {55 55 40 25} type Toggle
|
||||
}
|
||||
}
|
||||
MenuItem {} {
|
||||
label {&New}
|
||||
|
@ -364,9 +369,7 @@ main_window->redraw();}
|
|||
}
|
||||
MenuItem {} {
|
||||
label {&Open}
|
||||
callback {
|
||||
|
||||
char *path = read_line( user_config_dir, "default_path" );
|
||||
callback {char *path = read_line( user_config_dir, "default_path" );
|
||||
|
||||
const char *name = fl_dir_chooser( "Open Project", path );
|
||||
|
||||
|
@ -1107,7 +1110,7 @@ if ( logo_box->image() )
|
|||
code1 {o->label( NULL );}
|
||||
}
|
||||
Fl_Text_Editor notes_field {
|
||||
label {Notes:} selected
|
||||
label {Notes:}
|
||||
private xywh {20 420 480 245} color 47 selection_color 31 textsize 18 textcolor 92
|
||||
code0 {o->buffer( new Fl_Text_Buffer() );}
|
||||
code1 {o->buffer()->loadfile( "notes" );}
|
||||
|
|
|
@ -73,6 +73,7 @@ bool Timeline::snapping_on_hold = false;
|
|||
bool Timeline::snap_magnetic = true;
|
||||
bool Timeline::follow_playhead = true;
|
||||
bool Timeline::center_playhead = true;
|
||||
bool Timeline::playback_latency_compensation = false;
|
||||
|
||||
const float UPDATE_FREQ = 1.0f / 18.0f;
|
||||
|
||||
|
|
|
@ -155,6 +155,7 @@ public:
|
|||
static bool snap_magnetic;
|
||||
static bool follow_playhead;
|
||||
static bool center_playhead;
|
||||
static bool playback_latency_compensation;
|
||||
|
||||
Tempo_Sequence *tempo_track;
|
||||
Time_Sequence *time_track;
|
||||
|
|
|
@ -253,8 +253,8 @@ public:
|
|||
nframes_t process_input ( nframes_t nframes );
|
||||
nframes_t process_output ( nframes_t nframes );
|
||||
void seek ( nframes_t frame );
|
||||
void delay ( nframes_t frames );
|
||||
|
||||
void undelay ( nframes_t frames );
|
||||
void compute_latency_compensation ( void );
|
||||
void record ( Capture *c, nframes_t frame );
|
||||
void write ( Capture *c, sample_t *buf, nframes_t nframes );
|
||||
void finalize ( Capture *c, nframes_t frame );
|
||||
|
|
Loading…
Reference in New Issue