Browse Source

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

tags/non-daw-v1.2.0
Jonathan Moore Liles 10 years ago
parent
commit
2e49295320
6 changed files with 90 additions and 96 deletions
  1. +44
    -41
      timeline/src/Audio_Region.C
  2. +9
    -6
      timeline/src/Audio_Sequence.C
  3. +16
    -23
      timeline/src/Sequence_Region.C
  4. +7
    -5
      timeline/src/Sequence_Widget.C
  5. +12
    -19
      timeline/src/Sequence_Widget.H
  6. +2
    -2
      timeline/src/Timeline.H

+ 44
- 41
timeline/src/Audio_Region.C 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 )
{


+ 9
- 6
timeline/src/Audio_Sequence.C 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 );
}
}
}



+ 16
- 23
timeline/src/Sequence_Region.C 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


+ 7
- 5
timeline/src/Sequence_Widget.C 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 );



+ 12
- 19
timeline/src/Sequence_Widget.H 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();



+ 2
- 2
timeline/src/Timeline.H 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;



Loading…
Cancel
Save