@@ -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 ) | |||
{ | |||
@@ -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 ); | |||
} | |||
} | |||
} | |||
@@ -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 | |||
@@ -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 ); | |||
@@ -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(); | |||
@@ -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; | |||