| @@ -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; | |||