diff --git a/Audio_Track.H b/Audio_Track.H index ec013c6..efbc019 100644 --- a/Audio_Track.H +++ b/Audio_Track.H @@ -20,6 +20,7 @@ #pragma once #include "Track.H" +#include "Region.H" #include @@ -75,7 +76,7 @@ public: Region *r = new Region( c ); - r->offset( timeline.x_to_ts( Fl::event_x() ) ); + r->offset( timeline->x_to_ts( Fl::event_x() ) ); this->add( r ); diff --git a/Clip.C b/Clip.C index 15e150d..8f9f2c4 100644 --- a/Clip.C +++ b/Clip.C @@ -54,7 +54,7 @@ Clip::Clip ( void ) : _peaks( this ) /* return; */ /* } */ -/* if ( si.samplerate != timeline.sample_rate ) */ +/* if ( si.samplerate != timeline->sample_rate ) */ /* { */ /* printf( "error: samplerate mismatch!\n" ); */ /* return; */ @@ -90,7 +90,7 @@ Clip::from_file ( const char *filename ) goto invalid; } - if ( si.samplerate != timeline.sample_rate ) + if ( si.samplerate != timeline->sample_rate ) { printf( "error: samplerate mismatch!\n" ); goto invalid; diff --git a/Peaks.C b/Peaks.C index 5a5d1a4..08e2838 100644 --- a/Peaks.C +++ b/Peaks.C @@ -45,11 +45,11 @@ Peaks::peakbuffer Peaks::peakbuf; void Peaks::fill_buffer ( int s, int e ) const { - if ( timeline.fpp < _peaks->chunksize ) + if ( timeline->fpp < _peaks->chunksize ) { /* looks like we're going to have to switch to a higher resolution peak file or read directly from the source */ - read_peaks( s, e, (e - s) / timeline.fpp, timeline.fpp ); + read_peaks( s, e, (e - s) / timeline->fpp, timeline->fpp ); } else { @@ -144,9 +144,9 @@ Peaks::peak ( nframes_t start, nframes_t end ) const /* Is there a better way to return this? */ static Peak p; - if ( timeline.fpp < _peaks->chunksize ) + if ( timeline->fpp < _peaks->chunksize ) { - assert( timeline.fpp == peakbuf.buf->chunksize ); + assert( timeline->fpp == peakbuf.buf->chunksize ); start = (start - peakbuf.offset) / peakbuf.buf->chunksize; end = (end - peakbuf.offset) / peakbuf.buf->chunksize; @@ -175,7 +175,7 @@ Peaks::peak ( nframes_t start, nframes_t end ) const Peak & Peaks::operator[] ( int X ) const { - return peak( timeline.x_to_ts( X ), timeline.x_to_ts( X + 1 ) ); + return peak( timeline->x_to_ts( X ), timeline->x_to_ts( X + 1 ) ); } static diff --git a/Region.C b/Region.C index 1611c93..5386660 100644 --- a/Region.C +++ b/Region.C @@ -34,7 +34,7 @@ //using std::algorithm; using namespace std; -extern Timeline timeline; +extern Timeline *timeline; Fl_Boxtype Region::_box = FL_PLASTIC_UP_BOX; @@ -98,7 +98,7 @@ Region::trim ( enum trim_e t, int X ) { int d = X - x(); - long td = timeline.x_to_ts( d ); + long td = timeline->x_to_ts( d ); if ( td < 0 && _start < 0 - td ) td = 0 - _start; @@ -111,7 +111,7 @@ Region::trim ( enum trim_e t, int X ) case RIGHT: { int d = (x() + w()) - X; - long td = timeline.x_to_ts( d ); + long td = timeline->x_to_ts( d ); _end -= td; break; @@ -205,7 +205,7 @@ Region::handle ( int m ) Fl::event_state() & FL_CTRL ) { int d = (ox + X) - x(); - long td = timeline.x_to_ts( d ); + long td = timeline->x_to_ts( d ); nframes_t W = _end - _start; @@ -259,7 +259,7 @@ Region::handle ( int m ) return ret | 1; -// _offset = timeline.x_to_ts( x() ); +// _offset = timeline->x_to_ts( x() ); default: return Track_Widget::handle( m ); @@ -293,13 +293,13 @@ Region::draw ( int X, int Y, int W, int H ) return; int OX = scroll_x(); - int ox = timeline.ts_to_x( _offset ); + int ox = timeline->ts_to_x( _offset ); if ( ox > OX + _track->w() || ox < OX && ox + abs_w() < OX ) return; - int rw = timeline.ts_to_x( _end - _start ); + int rw = timeline->ts_to_x( _end - _start ); nframes_t end = _offset + ( _end - _start ); @@ -307,9 +307,9 @@ Region::draw ( int X, int Y, int W, int H ) nframes_t offset = 0; if ( ox < OX ) { - offset = timeline.x_to_ts( OX - ox ); + offset = timeline->x_to_ts( OX - ox ); - rw = timeline.ts_to_x( (_end - _start) - offset ); + rw = timeline->ts_to_x( (_end - _start) - offset ); } rw = min( rw, _track->w() ); @@ -326,7 +326,7 @@ Region::draw ( int X, int Y, int W, int H ) draw_waveform( rx, Y, rw, H, _clip, _start + offset, min( (_end - _start) - offset, _end), _scale, _selected ? _color : fl_invert_color( _color ) ); - timeline.draw_measure_lines( rx, Y, rw, H, _box_color ); + timeline->draw_measure_lines( rx, Y, rw, H, _box_color ); fl_color( FL_BLACK ); fl_line( rx, Y, rx, Y + H ); diff --git a/Tempo_Point.H b/Tempo_Point.H index 4e8360d..9cb3b4b 100644 --- a/Tempo_Point.H +++ b/Tempo_Point.H @@ -59,7 +59,7 @@ public: if ( m == FL_RELEASE ) { _track->sort(); - timeline.tracks->redraw(); + timeline->tracks->redraw(); } return r; } diff --git a/Time_Point.H b/Time_Point.H index b358b78..0808073 100644 --- a/Time_Point.H +++ b/Time_Point.H @@ -71,7 +71,7 @@ public: if ( m == FL_RELEASE ) { _track->sort(); - timeline.tracks->redraw(); + timeline->tracks->redraw(); } return r; } diff --git a/Timeline.C b/Timeline.C index 7abc3d1..f1daf24 100644 --- a/Timeline.C +++ b/Timeline.C @@ -20,7 +20,75 @@ #include "Timeline.H" #include "Tempo_Track.H" +#include "Time_Track.H" +#include "Audio_Track.H" +Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Group( X, Y, W, H, L ) +{ + { + Fl_Pack *o = new Fl_Pack( 0, 0, 800, 600, "rulers" ); + o->type( Fl_Pack::VERTICAL ); + + { + Tempo_Track *o = new Tempo_Track( 0, 0, 800, 24 ); + + o->color( FL_RED ); + + o->add( new Tempo_Point( 0, 120 ) ); + o->add( new Tempo_Point( 56000, 250 ) ); + + + tempo_track = o; + o->end(); + + } + + { + Time_Track *o = new Time_Track( 0, 24, 800, 24 ); + + o->color( fl_color_average( FL_RED, FL_WHITE, 0.50f ) ); + + o->add( new Time_Point( 0, 4, 4 ) ); + o->add( new Time_Point( 345344, 6, 8 ) ); + + time_track = o; + o->end(); + + } + + rulers = o; + o->end(); + } + + { + Fl_Scroll *o = new Fl_Scroll( 0, 24 * 2, 800, 600 - (24 * 3) ); + o->type( Fl_Scroll::VERTICAL ); + + sample_rate = 44100; + fpp = 256; + _beats_per_minute = 120; + length = sample_rate * 60 * 2; + + { + Fl_Pack *o = new Fl_Pack( 0, 0, 800, 5000 ); + o->type( Fl_Pack::VERTICAL ); + o->spacing( 10 ); + + { + Track *o = new Audio_Track( 0, 0, 800, 100 ); + o->end(); + } + + tracks = o; + o->end(); + } + + scroll = o; + o->end(); + } + + end(); +} float diff --git a/Timeline.H b/Timeline.H index 47c9a38..2946e0b 100644 --- a/Timeline.H +++ b/Timeline.H @@ -22,6 +22,7 @@ #include #include #include +#include #include "Clip.H" #include @@ -31,7 +32,7 @@ #include class Timeline; -extern Timeline timeline; +extern Timeline *timeline; #include "Track.H" // #include "Tempo_Track.H" @@ -45,7 +46,10 @@ class Time_Track; #include using std::list; -struct Timeline { +struct Timeline : public Fl_Group +{ + + int _old_position; enum snap_flags_e { SNAP_TO_REGION, @@ -73,6 +77,8 @@ struct Timeline { int _beats_per_bar; float _beats_per_minute; + Timeline ( int X, int Y, int W, int H, const char *L=0 ); + int ts_to_x( nframes_t ts ) { @@ -94,10 +100,79 @@ struct Timeline { void position ( int X ) { + _old_position = xoffset; + xoffset = x_to_ts( X ); + damage( FL_DAMAGE_SCROLL ); + rulers->damage( FL_DAMAGE_SCROLL ); tracks->damage( FL_DAMAGE_SCROLL ); } + +#define FOR_CHILDREN_OF( name, ind ) \ + for ( int i = (name) ->children(); i-- && ( (ind) = (name) ->child( i ) ); ) + + static void + draw_clip ( void * v, int X, int Y, int W, int H ) + { + Timeline *tl = (Timeline *)v; + + fl_push_clip( X, Y, W, H ); + + tl->tracks->redraw(); + tl->rulers->redraw(); + +/* FOR_CHILDREN_OF( tracks, o ) */ +/* { */ +/* tracks->draw_child( *o ); */ +/* tracks->draw_outside_label( *o ); */ +/* } */ + +/* FOR_CHILDREN_OF( rulers, o ) */ +/* { */ +/* tracks->draw_child( o ); */ +/* tracks->draw_outside_label( o ); */ +/* } */ + + fl_pop_clip(); + } + + +/* void */ +/* draw ( void ) */ +/* { */ +/* int X, Y, W, H; */ + +/* X = x(); */ +/* Y = tracks->y(); */ +/* W = w(); */ +/* H = tracks->h(); */ + +/* if ( damage() & FL_DAMAGE_ALL ) */ +/* { */ +/* draw_clip( this, X, Y, W, H ); */ +/* return; */ +/* } */ + +/* if ( damage() & FL_DAMAGE_SCROLL ) */ +/* { */ +/* fl_scroll( X, Y, W, H, _old_position - xoffset, Y, draw_clip, this ); */ +/* } */ + +/* if ( damage() & FL_DAMAGE_CHILD ) */ +/* { */ +/* // Fl_Widget *o; */ + +/* /\* FOR_CHILDREN_OF( tracks, o ) *\/ */ +/* /\* tracks->update_child( o ); *\/ */ + +/* /\* FOR_CHILDREN_OF( rulers, o ) *\/ */ +/* /\* rulers->update_child( o ); *\/ */ + +/* // fl_pop_clip() */ +/* } */ +/* } */ + }; diff --git a/Track.C b/Track.C index 3899689..18f9fc3 100644 --- a/Track.C +++ b/Track.C @@ -45,7 +45,7 @@ Track::draw ( void ) { Fl_Group::draw(); - timeline.draw_measure_lines( x(), y(), w(), h(), color() ); + timeline->draw_measure_lines( x(), y(), w(), h(), color() ); fl_push_clip( x(), y(), w(), h() ); @@ -70,7 +70,7 @@ Track_Widget * Track::event_widget ( void ) { // FIXME: doesn't handle overlap! - int ets = timeline.xoffset + timeline.x_to_ts( Fl::event_x() ); + int ets = timeline->xoffset + timeline->x_to_ts( Fl::event_x() ); for ( list ::iterator r = _widgets.begin(); r != _widgets.end(); r++ ) if ( ets > (*r)->offset() && ets < (*r)->offset() + (*r)->length() ) return (*r); @@ -130,7 +130,7 @@ Track::snap ( Track_Widget *r ) } } -// r->offset( timeline.x_to_ts( r->x() ) ); +// r->offset( timeline->x_to_ts( r->x() ) ); done: diff --git a/Track_Point.H b/Track_Point.H index c97bd17..7df457a 100644 --- a/Track_Point.H +++ b/Track_Point.H @@ -31,7 +31,7 @@ protected: public: int abs_w ( void ) const { return 10; } - nframes_t length ( void ) const { return timeline.x_to_ts( abs_w() ); } + nframes_t length ( void ) const { return timeline->x_to_ts( abs_w() ); } Track_Point ( ) { diff --git a/Track_Widget.H b/Track_Widget.H index 455f595..c505fac 100644 --- a/Track_Widget.H +++ b/Track_Widget.H @@ -54,16 +54,16 @@ public: Fl_Group * parent ( void ) const { return _track; } - int scroll_x ( void ) const { return timeline.ts_to_x( timeline.xoffset ); } - nframes_t scroll_ts ( void ) const { return timeline.xoffset; } + int scroll_x ( void ) const { return timeline->ts_to_x( timeline->xoffset ); } + nframes_t scroll_ts ( void ) const { return timeline->xoffset; } int y ( void ) const { return _track->y(); } int h ( void ) const { return _track->h(); } - int x ( void ) const { return _offset < timeline.xoffset ? -1 : min( 32767, _track->x() + timeline.ts_to_x( _offset - timeline.xoffset ) ); } + int x ( void ) const { return _offset < timeline->xoffset ? -1 : min( 32767, _track->x() + timeline->ts_to_x( _offset - timeline->xoffset ) ); } virtual int w ( void ) const { - int tx = timeline.ts_to_x( _offset ); + int tx = timeline->ts_to_x( _offset ); int rw; if ( tx < scroll_x() ) @@ -74,8 +74,8 @@ public: return min( rw, _track->w() ); } - int abs_x ( void ) const { return timeline.ts_to_x( timeline.xoffset ); } - virtual int abs_w ( void ) const { return timeline.ts_to_x( _end - _start ); } + int abs_x ( void ) const { return timeline->ts_to_x( timeline->xoffset ); } + virtual int abs_w ( void ) const { return timeline->ts_to_x( _end - _start ); } Fl_Color color ( void ) { return _color; } @@ -167,7 +167,7 @@ public: if ( align & FL_ALIGN_CLIP ) fl_push_clip( X, Y, W, H ); int dx = 0; - int tx = timeline.ts_to_x( _offset ); + int tx = timeline->ts_to_x( _offset ); if ( tx < scroll_x() ) dx = min( 32767, scroll_x() - tx ); @@ -212,7 +212,7 @@ public: { int nx = ox + X; - _offset = timeline.x_to_ts( nx ) + timeline.xoffset; + _offset = timeline->x_to_ts( nx ) + timeline->xoffset; _track->snap( this ); } @@ -226,9 +226,9 @@ public: { /* this drag needs to scroll */ - nframes_t pos = timeline.xoffset; + nframes_t pos = timeline->xoffset; - nframes_t d = timeline.x_to_ts( 100 ); + nframes_t d = timeline->x_to_ts( 100 ); if ( X <= _track->x() ) { @@ -241,9 +241,9 @@ public: else pos += d; - timeline.xoffset = pos; + timeline->xoffset = pos; - timeline.tracks->redraw(); + timeline->tracks->redraw(); } diff --git a/Waveform.C b/Waveform.C index 0b1a92c..62a8c36 100644 --- a/Waveform.C +++ b/Waveform.C @@ -50,11 +50,11 @@ draw_waveform ( int X, int Y, int W, int H, Clip *_clip, nframes_t _start, nfram int j; - int start = timeline.ts_to_x( _start ); + int start = timeline->ts_to_x( _start ); { _clip->peaks()->fill_buffer( _start, - _start + timeline.x_to_ts( W ) ); + _start + timeline->x_to_ts( W ) ); } j = start; diff --git a/main.C b/main.C index 6dd2949..37c9765 100644 --- a/main.C +++ b/main.C @@ -48,41 +48,39 @@ #include "const.h" - -Timeline timeline; - +Timeline *timeline; void cb_scroll ( Fl_Widget *w, void *v ) { Scalebar *sb = (Scalebar*)w; - timeline.fpp = sb->zoom() * 256; - timeline.fpp = max( min( timeline.fpp, 4096.0f ), (float)2 ); + timeline->fpp = sb->zoom() * 256; + timeline->fpp = max( min( timeline->fpp, 4096.0f ), (float)2 ); - int maxx = timeline.ts_to_x( timeline.length ); + int maxx = timeline->ts_to_x( timeline->length ); sb->range( 0, maxx ); // sb->value( sb->value(), maxx // sb->slider_size( sb->w() / maxx ); // ((Fl_Scrollbar*)sb)->value( sb->value(), 60, 10, maxx ); - timeline.position( sb->value() ); + timeline->position( sb->value() ); -/* timeline.xoffset = timeline.x_to_ts( sb->value() ); */ -/* // timeline.tracks->redraw(); */ -/* timeline.scroll->redraw(); */ +/* timeline->xoffset = timeline->x_to_ts( sb->value() ); */ +/* // timeline->tracks->redraw(); */ +/* timeline->scroll->redraw(); */ - printf( "%lu\n", timeline.xoffset ); + printf( "%lu\n", timeline->xoffset ); - for ( int i = timeline.tracks->children(); i-- ; ) + for ( int i = timeline->tracks->children(); i-- ; ) { - Fl_Group *track = (Fl_Group*)timeline.tracks->child( i ); + Fl_Group *track = (Fl_Group*)timeline->tracks->child( i ); track->damage( FL_DAMAGE_SCROLL ); } - for ( int i = timeline.rulers->children(); i-- ; ) + for ( int i = timeline->rulers->children(); i-- ; ) { - Fl_Group *track = (Fl_Group*)timeline.rulers->child( i ); + Fl_Group *track = (Fl_Group*)timeline->rulers->child( i ); track->damage( FL_DAMAGE_SCROLL ); } @@ -102,116 +100,22 @@ cb_scroll ( Fl_Widget *w, void *v ) int main ( int argc, char **argv ) { - Fl_Double_Window *main_window = new Fl_Double_Window( 0, 0, 800, 600 ); Fl::get_system_colors(); Fl::scheme( "plastic" ); - { - Fl_Pack *o = new Fl_Pack( 0, 0, 800, 24 * 2, "rulers" ); - o->type( Fl_Pack::VERTICAL ); + timeline = new Timeline( 0, 0, 800, 600, "Timeline" ); - { - Tempo_Track *o = new Tempo_Track( 0, 0, 800, 24 ); +// Region *wave = new Region( Clip::from_file( "streambass8.wav" ) ); - o->color( FL_RED ); +/* track1->next( track2 ); */ +/* track2->prev( track1 ); */ -// tempo_track->label( "tempo map" ); - o->add( new Tempo_Point( 0, 120 ) ); - o->add( new Tempo_Point( 56000, 250 ) ); - - o->end(); - - timeline.tempo_track = o; - } - - { - Time_Track *o = new Time_Track( 0, 24, 800, 24 ); - - o->color( fl_color_average( FL_RED, FL_WHITE, 0.50f ) ); - - o->add( new Time_Point( 0, 4, 4 ) ); - o->add( new Time_Point( 345344, 6, 8 ) ); - - o->end(); - - timeline.time_track = o; - } - - timeline.rulers = o; - o->end(); - } - - timeline.scroll = new Fl_Scroll( 0, 24 * 2, 800, 600 - (24 * 3) ); - timeline.scroll->type( Fl_Scroll::VERTICAL ); - timeline.fpp = 256; - timeline._beats_per_minute = 120; - timeline.length = 48000 * 60 * 2; - - - timeline.sample_rate = 44100; - - - timeline.tracks = new Fl_Pack( 0, 0, 800, 5000 ); - timeline.tracks->type( Fl_Pack::VERTICAL ); - timeline.tracks->spacing( 20 ); - - -// Fl_Group *pack = new Fl_Group( 0, 0, 5000, 600 ); - - - Track *track1 = new Audio_Track( 40, 0, 800, 100 ); - -// pack->type( Fl_Pack::VERTICAL ); -// pack->box( FL_DOWN_BOX ); - - // Region *wave = new Region( 0, 0, 5000, 100, "foo" ); - - Region *wave = new Region( Clip::from_file( "streambass8.wav" ) ); - -// wave->resize( 0, 0, 500, 100 ); - - wave->offset( 1024 ); - wave->end( 3000 ); - -/* wave->color( FL_CYAN ); */ -/* wave->selection_color( fl_darker( FL_GRAY ) ); */ -/* wave->selection_color( FL_GREEN ); */ - - track1->add( wave ); - - Region *wave3 = new Region( *wave ); - wave3->offset( 4000 ); - track1->add( wave3 ); - - track1->end(); - - Track *track2 = new Audio_Track( 40, 0, 5000, 100 ); - - // Region *wave2 = new Region( 0, 0, 350, 100, "bar" ); - - Region *wave2 = new Region( *wave ); - -/* wave2->peaks( peaks ); */ -/* wave2->start( 300 ); */ -/* wave2->end( len ); */ - - track2->add( wave2 ); - - - track2->end(); - - track1->next( track2 ); - track2->prev( track1 ); - - timeline.tracks->end(); - timeline.scroll->end(); - - timeline.scrollbar = new Scalebar( 0, 600 - 24, 800, 24 ); - timeline.scrollbar->range( 0, 48000 * 2 ); - timeline.scrollbar->type( 1 ); - timeline.scrollbar->callback( cb_scroll, 0 ); + timeline->scrollbar = new Scalebar( 0, 600 - 24, 800, 24 ); + timeline->scrollbar->range( 0, 48000 * 2 ); + timeline->scrollbar->type( 1 ); + timeline->scrollbar->callback( cb_scroll, 0 ); main_window->end(); main_window->show();