Timeline: Fix some issues with audio region waveform alignment when drawing.
This commit is contained in:
parent
6bbe69e712
commit
2e49295320
|
@ -514,13 +514,14 @@ Audio_Region::draw ( void )
|
||||||
|
|
||||||
/* calculate waveform offset due to scrolling */
|
/* calculate waveform offset due to scrolling */
|
||||||
/* offset is the number of frames into the waveform the value of X translates to */
|
/* offset is the number of frames into the waveform the value of X translates to */
|
||||||
nframes_t x_frame = timeline->xoffset + timeline->x_to_ts( X - _sequence->drawable_x() );
|
|
||||||
|
/* this is the timestamp at where we'll actually be drawing. */
|
||||||
|
nframes_t x_frame = timeline->x_to_ts(
|
||||||
|
timeline->ts_to_x( timeline->xoffset ) + ( X - _sequence->drawable_x() ) );
|
||||||
|
|
||||||
nframes_t offset = 0;
|
nframes_t offset = 0;
|
||||||
|
|
||||||
if ( x_frame < start() )
|
if ( x_frame > start() )
|
||||||
/* sometimes X is one pixel too soon... */
|
|
||||||
offset = 0;
|
|
||||||
else
|
|
||||||
offset = x_frame - start();
|
offset = x_frame - start();
|
||||||
|
|
||||||
nframes_t fo = 0;
|
nframes_t fo = 0;
|
||||||
|
@ -543,37 +544,34 @@ Audio_Region::draw ( void )
|
||||||
int peaks = 0;
|
int peaks = 0;
|
||||||
Peak *pbuf = NULL;
|
Peak *pbuf = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
Fl_Color fg_color = FL_FOREGROUND_COLOR;
|
||||||
|
Fl_Color bg_color = FL_BACKGROUND_COLOR;
|
||||||
|
|
||||||
|
if ( !active_r() )
|
||||||
|
{
|
||||||
|
fg_color = fl_inactive(fg_color);
|
||||||
|
bg_color = fl_inactive(bg_color);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
nframes_t start = _r->offset;
|
|
||||||
|
|
||||||
nframes_t loop_frames_needed = _loop ? _loop : total_frames_needed;
|
nframes_t loop_frames_needed = _loop ? _loop : total_frames_needed;
|
||||||
int loop_peaks_needed = timeline->ts_to_x( loop_frames_needed );
|
int loop_peaks_needed = timeline->ts_to_x( loop_frames_needed );
|
||||||
|
|
||||||
Fl_Color fg_color = FL_FOREGROUND_COLOR;
|
|
||||||
Fl_Color bg_color = FL_BACKGROUND_COLOR;
|
|
||||||
|
|
||||||
if ( !active_r() )
|
nframes_t start = _r->offset;
|
||||||
{
|
|
||||||
fg_color = fl_inactive(fg_color);
|
|
||||||
bg_color = fl_inactive(bg_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! fo ) /* first loop... */
|
if ( ! fo ) /* first loop... */
|
||||||
{
|
{
|
||||||
if ( _loop )
|
|
||||||
start += offset % _loop;
|
|
||||||
else
|
|
||||||
start += offset;
|
|
||||||
|
|
||||||
/* DMESSAGE( "offset = %lu", (unsigned long) offset ); */
|
|
||||||
/* DMESSAGE( "loop peaks needed = %d", loop_peaks_needed ); */
|
|
||||||
|
|
||||||
if ( _loop )
|
if ( _loop )
|
||||||
{
|
{
|
||||||
|
// start += offset;
|
||||||
|
start += offset % _loop;
|
||||||
loop_frames_needed -= offset % loop_frames_needed;
|
loop_frames_needed -= offset % loop_frames_needed;
|
||||||
loop_peaks_needed = timeline->ts_to_x( loop_frames_needed );
|
loop_peaks_needed = timeline->ts_to_x( loop_frames_needed );
|
||||||
}
|
}
|
||||||
/* DMESSAGE( "loop peaks needed = %d", loop_peaks_needed ); */
|
else
|
||||||
|
start += offset;
|
||||||
|
|
||||||
assert( loop_peaks_needed >= 0 );
|
assert( loop_peaks_needed >= 0 );
|
||||||
}
|
}
|
||||||
|
@ -594,9 +592,9 @@ Audio_Region::draw ( void )
|
||||||
_clip->peaks()->peakfile_ready();
|
_clip->peaks()->peakfile_ready();
|
||||||
|
|
||||||
if ( _clip->read_peaks( timeline->fpp(),
|
if ( _clip->read_peaks( timeline->fpp(),
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
&peaks, &pbuf, &channels ) )
|
&peaks, &pbuf, &channels ) )
|
||||||
{
|
{
|
||||||
Waveform::scale( pbuf, peaks * channels, _scale );
|
Waveform::scale( pbuf, peaks * channels, _scale );
|
||||||
|
|
||||||
|
@ -606,9 +604,9 @@ Audio_Region::draw ( void )
|
||||||
|
|
||||||
if ( _clip->peaks()->needs_more_peaks() && ! transport->rolling )
|
if ( _clip->peaks()->needs_more_peaks() && ! transport->rolling )
|
||||||
{
|
{
|
||||||
/* maybe create a thread to make the peaks */
|
/* maybe create a thread to make the peaks */
|
||||||
/* this function will just return if there's nothing to do. */
|
/* this function will just return if there's nothing to do. */
|
||||||
_clip->peaks()->make_peaks_asynchronously( Audio_Region::peaks_ready_callback, this );
|
_clip->peaks()->make_peaks_asynchronously( Audio_Region::peaks_ready_callback, this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -634,6 +632,22 @@ Audio_Region::draw ( void )
|
||||||
else
|
else
|
||||||
;
|
;
|
||||||
// WARNING( "Pbuf == %p, peaks = %lu", pbuf, (unsigned long)peaks );
|
// WARNING( "Pbuf == %p, peaks = %lu", pbuf, (unsigned long)peaks );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( _loop )
|
||||||
|
{
|
||||||
|
const int lx = sequence()->drawable_x() + timeline->ts_to_x( ( this->start() + _loop ) - timeline->xoffset );
|
||||||
|
|
||||||
|
if ( lx < X + W )
|
||||||
|
{
|
||||||
|
fl_color( fl_darker( FL_CYAN ) );
|
||||||
|
fl_line( lx, y(), lx, y() + h() );
|
||||||
|
fl_line( lx - 3, y(), lx + 3, y() );
|
||||||
|
fl_line( lx - 3, y() + h() - 1, lx + 3, y() + h() - 1 );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( peaks < loop_peaks_needed )
|
if ( peaks < loop_peaks_needed )
|
||||||
{
|
{
|
||||||
|
@ -641,22 +655,11 @@ Audio_Region::draw ( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
fo += loop_frames_needed;
|
fo += loop_frames_needed;
|
||||||
|
|
||||||
}
|
}
|
||||||
while ( _loop && fo < total_frames_needed );
|
while ( _loop && fo < total_frames_needed );
|
||||||
|
|
||||||
|
|
||||||
if ( _loop && offset < _loop )
|
|
||||||
{
|
|
||||||
const int lx = get_x( start() + _loop );
|
|
||||||
|
|
||||||
if ( lx < X + W )
|
|
||||||
{
|
|
||||||
fl_color( FL_RED );
|
|
||||||
fl_line_style( FL_DASH, 0 );
|
|
||||||
fl_line( lx, y(), lx, y() + h() );
|
|
||||||
fl_line_style( FL_SOLID, 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( _adjusting_gain )
|
if ( _adjusting_gain )
|
||||||
{
|
{
|
||||||
|
|
|
@ -233,15 +233,18 @@ Audio_Sequence::draw ( void )
|
||||||
(o->x() + o->w()) - (*r)->x(),
|
(o->x() + o->w()) - (*r)->x(),
|
||||||
o->h() );
|
o->h() );
|
||||||
|
|
||||||
cairo_t *cc = Fl::cairo_cc();
|
if ( b.w > 0 )
|
||||||
|
{
|
||||||
|
cairo_t *cc = Fl::cairo_cc();
|
||||||
|
|
||||||
cairo_set_operator( cc, CAIRO_OPERATOR_HSL_COLOR );
|
cairo_set_operator( cc, CAIRO_OPERATOR_HSL_COLOR );
|
||||||
cairo_set_source_rgba( cc, 1, 1, 0, 0.80 );
|
cairo_set_source_rgba( cc, 1, 1, 0, 0.80 );
|
||||||
cairo_rectangle( cc, b.x, b.y, b.w, b.h );
|
cairo_rectangle( cc, b.x, b.y, b.w, b.h );
|
||||||
|
|
||||||
cairo_fill( cc );
|
cairo_fill( cc );
|
||||||
|
|
||||||
cairo_set_operator( cc, CAIRO_OPERATOR_OVER );
|
cairo_set_operator( cc, CAIRO_OPERATOR_OVER );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,41 +70,34 @@ Sequence_Region::set ( Log_Entry &e )
|
||||||
void
|
void
|
||||||
Sequence_Region::trim_left ( nframes_t where )
|
Sequence_Region::trim_left ( nframes_t where )
|
||||||
{
|
{
|
||||||
int64_t td = (int64_t)where - _r->start;
|
nframes_t f = where;
|
||||||
|
|
||||||
/* beyond the beginning */
|
|
||||||
if ( td < 0 && _r->offset < (nframes_t)( 0 - td ) )
|
|
||||||
td = (int64_t)0 - _r->offset;
|
|
||||||
|
|
||||||
if ( td > 0 && (nframes_t)td >= _r->length )
|
|
||||||
td = (int64_t)_r->length - timeline->x_to_ts( 1 );
|
|
||||||
|
|
||||||
_r->trim_left( 0 - td );
|
|
||||||
|
|
||||||
nframes_t f = _r->start;
|
|
||||||
|
|
||||||
/* snap to beat/bar lines */
|
/* snap to beat/bar lines */
|
||||||
if ( timeline->nearest_line( &f ) )
|
if ( timeline->nearest_line( &f ) )
|
||||||
_r->set_left( f );
|
where = f;
|
||||||
|
|
||||||
|
if ( where > _r->start + _r->length )
|
||||||
|
where = _r->start + _r->length;
|
||||||
|
|
||||||
|
if ( where < _r->start && _r->offset < _r->start - where )
|
||||||
|
where = _r->start - _r->offset;
|
||||||
|
|
||||||
|
_r->set_left( where );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Sequence_Region::trim_right ( nframes_t where )
|
Sequence_Region::trim_right ( nframes_t where )
|
||||||
{
|
{
|
||||||
int64_t td = (int64_t)( _r->start + _r->length ) - where;
|
nframes_t f = where;
|
||||||
|
|
||||||
if ( td >= 0 && _r->length < (nframes_t)td )
|
|
||||||
td = _r->length - timeline->x_to_ts( 1 );
|
|
||||||
|
|
||||||
_r->trim_right( 0 - td );
|
|
||||||
|
|
||||||
nframes_t f = _r->start + _r->length;
|
|
||||||
|
|
||||||
/* snap to beat/bar lines */
|
/* snap to beat/bar lines */
|
||||||
if ( timeline->nearest_line( &f ) )
|
if ( timeline->nearest_line( &f ) )
|
||||||
_r->set_right( f );
|
where = f;
|
||||||
|
|
||||||
|
if ( where < _r->start )
|
||||||
|
where = _r->start;
|
||||||
|
|
||||||
|
_r->set_right( where );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -442,7 +442,7 @@ Sequence_Widget::handle ( int m )
|
||||||
|
|
||||||
if ( ! _drag )
|
if ( ! _drag )
|
||||||
{
|
{
|
||||||
begin_drag ( Drag( x() - X, y() - Y, x_to_offset( X ) ) );
|
begin_drag ( Drag( x() - X, y() - Y, start() - x_to_offset( X ) ) );
|
||||||
_log.hold();
|
_log.hold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,11 +462,13 @@ Sequence_Widget::handle ( int m )
|
||||||
|
|
||||||
const nframes_t of = timeline->x_to_offset( X );
|
const nframes_t of = timeline->x_to_offset( X );
|
||||||
|
|
||||||
if ( of >= _drag->start )
|
int64_t s = (int64_t)of - _drag->offset;
|
||||||
start( of - _drag->start );
|
|
||||||
else
|
if ( s < 0 )
|
||||||
start( 0 );
|
s = 0;
|
||||||
|
|
||||||
|
start(s);
|
||||||
|
|
||||||
if ( Sequence_Widget::_current == this )
|
if ( Sequence_Widget::_current == this )
|
||||||
sequence()->snap( this );
|
sequence()->snap( this );
|
||||||
|
|
||||||
|
|
|
@ -37,9 +37,10 @@ struct Drag
|
||||||
int y;
|
int y;
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
nframes_t start;
|
// nframes_t start;
|
||||||
|
int64_t offset;
|
||||||
|
|
||||||
Drag( int X, int Y, nframes_t start=0 ) : x( X ), y( Y ), start( start ) { state = 0; }
|
Drag( int X, int Y, uint64_t offset=0 ) : x( X ), y( Y ), offset( offset ) { state = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* most common position description. /offset/ is only used by Regions,
|
/* most common position description. /offset/ is only used by Regions,
|
||||||
|
@ -50,20 +51,6 @@ struct Range
|
||||||
nframes_t offset; /* first sample from clip */
|
nframes_t offset; /* first sample from clip */
|
||||||
nframes_t length; /* total number of samples */
|
nframes_t length; /* total number of samples */
|
||||||
|
|
||||||
void
|
|
||||||
trim_left ( long n )
|
|
||||||
{
|
|
||||||
start -= n;
|
|
||||||
offset -= n;
|
|
||||||
length += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
trim_right ( long n )
|
|
||||||
{
|
|
||||||
length += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
set_left ( nframes_t f )
|
set_left ( nframes_t f )
|
||||||
{
|
{
|
||||||
|
@ -221,11 +208,17 @@ public:
|
||||||
|
|
||||||
virtual int w ( void ) const
|
virtual int w ( void ) const
|
||||||
{
|
{
|
||||||
int tx = timeline->ts_to_x( _r->start );
|
// int tx = timeline->ts_to_x( _r->start );
|
||||||
|
|
||||||
int rw;
|
int rw;
|
||||||
if ( tx < scroll_x() )
|
|
||||||
rw = abs_w() - (scroll_x() - tx);
|
if ( _r->start < timeline->xoffset )
|
||||||
|
{
|
||||||
|
if ( _r->start + _r->length < timeline->xoffset )
|
||||||
|
rw = 0;
|
||||||
|
else
|
||||||
|
rw = timeline->ts_to_x( ( _r->start + _r->length ) - timeline->xoffset );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rw = abs_w();
|
rw = abs_w();
|
||||||
|
|
||||||
|
|
|
@ -199,8 +199,8 @@ public:
|
||||||
nframes_t length ( void ) const;
|
nframes_t length ( void ) const;
|
||||||
void sample_rate ( nframes_t r ) { _sample_rate = r; }
|
void sample_rate ( nframes_t r ) { _sample_rate = r; }
|
||||||
nframes_t sample_rate ( void ) const { return _sample_rate; }
|
nframes_t sample_rate ( void ) const { return _sample_rate; }
|
||||||
int ts_to_x( nframes_t ts ) const { return ts >> _fpp; }
|
int ts_to_x( nframes_t ts ) const { return ts >> _fpp; }
|
||||||
nframes_t x_to_ts ( int x ) const { return x << _fpp; }
|
nframes_t x_to_ts ( int x ) const { return (nframes_t)x << _fpp; }
|
||||||
nframes_t x_to_offset ( int x ) const;
|
nframes_t x_to_offset ( int x ) const;
|
||||||
int offset_to_x ( nframes_t frame ) const;
|
int offset_to_x ( nframes_t frame ) const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue