@@ -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() ) | |||||
/* sometimes X is one pixel too soon... */ | |||||
offset = 0; | |||||
else | |||||
if ( x_frame > start() ) | |||||
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() ) | |||||
{ | |||||
fg_color = fl_inactive(fg_color); | |||||
bg_color = fl_inactive(bg_color); | |||||
} | |||||
nframes_t start = _r->offset; | |||||
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, | |||||
end, | |||||
&peaks, &pbuf, &channels ) ) | |||||
start, | |||||
end, | |||||
&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 */ | |||||
/* 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 | 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_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 ); | |||||
} | |||||
} | } | ||||
} | } | ||||
@@ -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; | |||||
/* 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 */ | /* 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; | |||||
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 */ | /* 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 ) | |||||
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 ) | 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; } | |||||
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; | nframes_t x_to_offset ( int x ) const; | ||||
int offset_to_x ( nframes_t frame ) const; | int offset_to_x ( nframes_t frame ) const; | ||||