Timeline: Fix some issues with audio region waveform alignment when drawing.

This commit is contained in:
Jonathan Moore Liles 2013-09-23 23:33:24 -07:00
parent 6bbe69e712
commit 2e49295320
6 changed files with 90 additions and 96 deletions

View File

@ -514,13 +514,14 @@ Audio_Region::draw ( void )
/* calculate waveform offset due to scrolling */
/* 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;
if ( x_frame < start() )
/* sometimes X is one pixel too soon... */
offset = 0;
else
if ( x_frame > start() )
offset = x_frame - start();
nframes_t fo = 0;
@ -543,37 +544,34 @@ Audio_Region::draw ( void )
int peaks = 0;
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 {
nframes_t start = _r->offset;
nframes_t loop_frames_needed = _loop ? _loop : total_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() )
{
fg_color = fl_inactive(fg_color);
bg_color = fl_inactive(bg_color);
}
nframes_t start = _r->offset;
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 )
{
// start += offset;
start += offset % _loop;
loop_frames_needed -= offset % 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 );
}
@ -594,9 +592,9 @@ Audio_Region::draw ( void )
_clip->peaks()->peakfile_ready();
if ( _clip->read_peaks( timeline->fpp(),
start,
end,
&peaks, &pbuf, &channels ) )
start,
end,
&peaks, &pbuf, &channels ) )
{
Waveform::scale( pbuf, peaks * channels, _scale );
@ -606,9 +604,9 @@ Audio_Region::draw ( void )
if ( _clip->peaks()->needs_more_peaks() && ! transport->rolling )
{
/* maybe create a thread to make the peaks */
/* this function will just return if there's nothing to do. */
_clip->peaks()->make_peaks_asynchronously( Audio_Region::peaks_ready_callback, this );
/* maybe create a thread to make the peaks */
/* this function will just return if there's nothing to do. */
_clip->peaks()->make_peaks_asynchronously( Audio_Region::peaks_ready_callback, this );
}
}
else
@ -634,6 +632,22 @@ Audio_Region::draw ( void )
else
;
// 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 )
{
@ -641,22 +655,11 @@ Audio_Region::draw ( void )
}
fo += loop_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 )
{

View File

@ -233,15 +233,18 @@ Audio_Sequence::draw ( void )
(o->x() + o->w()) - (*r)->x(),
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_source_rgba( cc, 1, 1, 0, 0.80 );
cairo_rectangle( cc, b.x, b.y, b.w, b.h );
cairo_set_operator( cc, CAIRO_OPERATOR_HSL_COLOR );
cairo_set_source_rgba( cc, 1, 1, 0, 0.80 );
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 );
}
}
}

View File

@ -70,41 +70,34 @@ Sequence_Region::set ( Log_Entry &e )
void
Sequence_Region::trim_left ( nframes_t where )
{
int64_t td = (int64_t)where - _r->start;
/* 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;
nframes_t f = where;
/* snap to beat/bar lines */
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
Sequence_Region::trim_right ( nframes_t where )
{
int64_t td = (int64_t)( _r->start + _r->length ) - 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;
nframes_t f = where;
/* snap to beat/bar lines */
if ( timeline->nearest_line( &f ) )
_r->set_right( f );
where = f;
if ( where < _r->start )
where = _r->start;
_r->set_right( where );
}
void

View File

@ -442,7 +442,7 @@ Sequence_Widget::handle ( int m )
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();
}
@ -462,11 +462,13 @@ Sequence_Widget::handle ( int m )
const nframes_t of = timeline->x_to_offset( X );
if ( of >= _drag->start )
start( of - _drag->start );
else
start( 0 );
int64_t s = (int64_t)of - _drag->offset;
if ( s < 0 )
s = 0;
start(s);
if ( Sequence_Widget::_current == this )
sequence()->snap( this );

View File

@ -37,9 +37,10 @@ struct Drag
int y;
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,
@ -50,20 +51,6 @@ struct Range
nframes_t offset; /* first sample from clip */
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
set_left ( nframes_t f )
{
@ -221,11 +208,17 @@ public:
virtual int w ( void ) const
{
int tx = timeline->ts_to_x( _r->start );
// int tx = timeline->ts_to_x( _r->start );
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
rw = abs_w();

View File

@ -199,8 +199,8 @@ public:
nframes_t length ( void ) const;
void sample_rate ( nframes_t r ) { _sample_rate = r; }
nframes_t sample_rate ( void ) const { return _sample_rate; }
int ts_to_x( nframes_t ts ) const { return ts >> _fpp; }
nframes_t x_to_ts ( int x ) const { return x << _fpp; }
int ts_to_x( nframes_t ts ) const { return ts >> _fpp; }
nframes_t x_to_ts ( int x ) const { return (nframes_t)x << _fpp; }
nframes_t x_to_offset ( int x ) const;
int offset_to_x ( nframes_t frame ) const;