| @@ -44,6 +44,21 @@ Loggable::open ( const char *filename ) | |||
| return false; | |||
| } | |||
| /* TODO: replay log here */ | |||
| /* FIXME: handle transactions!!! */ | |||
| { | |||
| char buf[BUFSIZ]; | |||
| while ( fscanf( _fp, "%[^\n]\n", buf ) == 1 ) | |||
| { | |||
| do_this( buf, false ); | |||
| } | |||
| } | |||
| return true; | |||
| } | |||
| @@ -116,7 +131,9 @@ bool | |||
| Loggable::do_this ( const char *s, bool reverse ) | |||
| { | |||
| int id; | |||
| sscanf( s, "%*s %X ", &id ); | |||
| if ( ! ( sscanf( s, "%*s %X ", &id ) > 0 ) ) | |||
| return false; | |||
| Loggable *l = find( id ); | |||
| // assert( l ); | |||
| @@ -328,6 +345,19 @@ Loggable::log ( const char *fmt, ... ) | |||
| void | |||
| Loggable::flush ( void ) | |||
| { | |||
| if ( ! _fp ) | |||
| { | |||
| printf( "error: no log file open!\n" ); | |||
| while ( ! _transaction.empty() ) | |||
| { | |||
| free( _transaction.front() ); | |||
| _transaction.pop(); | |||
| } | |||
| return; | |||
| } | |||
| int n = _transaction.size(); | |||
| if ( n > 1 ) | |||
| @@ -128,6 +128,9 @@ public: | |||
| _id = id; | |||
| /* make sure it'll fit */ | |||
| _loggables.reserve( _id ); | |||
| assert( ! _loggables[ _id - 1 ] ); | |||
| _loggables[ _id - 1 ] = this; | |||
| @@ -8,6 +8,8 @@ SRCS= \ | |||
| Timeline.C \ | |||
| Track_Header.C \ | |||
| Track_Widget.C \ | |||
| Tempo_Point.C \ | |||
| Time_Point.C \ | |||
| Peaks.C \ | |||
| Audio_File.C \ | |||
| Audio_File_SF.C \ | |||
| @@ -0,0 +1,112 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2008 Jonathan Moore Liles */ | |||
| /* */ | |||
| /* This program is free software; you can redistribute it and/or modify it */ | |||
| /* under the terms of the GNU General Public License as published by the */ | |||
| /* Free Software Foundation; either version 2 of the License, or (at your */ | |||
| /* option) any later version. */ | |||
| /* */ | |||
| /* This program is distributed in the hope that it will be useful, but WITHOUT */ | |||
| /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ | |||
| /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ | |||
| /* more details. */ | |||
| /* */ | |||
| /* You should have received a copy of the GNU General Public License along */ | |||
| /* with This program; see the file COPYING. If not,write to the Free Software */ | |||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
| /*******************************************************************************/ | |||
| #include "Tempo_Point.H" | |||
| #include "Tempo_Track.H" | |||
| #include "Timeline.H" // for timeline->tempo_track | |||
| char ** | |||
| Tempo_Point::get ( void ) | |||
| { | |||
| char **sa = (char**)malloc( sizeof( char* ) * 4 ); | |||
| int i = 0; | |||
| asprintf( &sa[i++], ":x %lu", _r->offset ); | |||
| asprintf( &sa[i++], ":tempo %.2f", _tempo ); | |||
| sa[i] = NULL; | |||
| return sa; | |||
| } | |||
| void | |||
| Tempo_Point::set ( char **sa ) | |||
| { | |||
| for ( int i = 0; sa[i]; ++i ) | |||
| { | |||
| char *s = sa[i]; | |||
| strtok( s, " " ); | |||
| char *v = s + strlen( s ) + 1; | |||
| if ( ! strcmp( s, ":x" ) ) | |||
| _r->offset = atol( v ); | |||
| else if ( ! strcmp( s, ":tempo" ) ) | |||
| _tempo = atof( v ); | |||
| /* FIXME: we need to add this to the time track on creation!!! */ | |||
| timeline->tempo_track->add( this ); | |||
| free( s ); | |||
| } | |||
| free( sa ); | |||
| timeline->redraw(); | |||
| _make_label(); | |||
| } | |||
| /* for loggable */ | |||
| Loggable * | |||
| Tempo_Point::create ( char **sa ) | |||
| { | |||
| Tempo_Point *r = new Tempo_Point; | |||
| r->set( sa ); | |||
| return (Loggable *)r; | |||
| } | |||
| Tempo_Point::Tempo_Point ( nframes_t when, float bpm ) | |||
| { | |||
| _tempo = bpm; | |||
| _r->offset = when; | |||
| _make_label(); | |||
| log_create(); | |||
| } | |||
| Tempo_Point::~Tempo_Point ( ) | |||
| { | |||
| if ( _label ) delete[] _label; | |||
| log_destroy(); | |||
| } | |||
| int | |||
| Tempo_Point::handle ( int m ) | |||
| { | |||
| int r = Track_Widget::handle( m ); | |||
| if ( m == FL_RELEASE ) | |||
| { | |||
| _track->sort(); | |||
| timeline->redraw(); | |||
| } | |||
| return r; | |||
| } | |||
| @@ -20,8 +20,7 @@ | |||
| #pragma once | |||
| #include "Track_Point.H" | |||
| #define __CLASS__ "Tempo_Point" | |||
| // #include "Tempo_Track.H" | |||
| class Tempo_Point : public Track_Point | |||
| { | |||
| @@ -40,88 +39,20 @@ protected: | |||
| const char *class_name ( void ) { return "Tempo_Point"; } | |||
| char ** get ( void ) | |||
| { | |||
| char **sa = (char**)malloc( sizeof( char* ) * 4 ); | |||
| int i = 0; | |||
| asprintf( &sa[i++], ":track 0x%X", _track ? _track->id() : 0 ); | |||
| asprintf( &sa[i++], ":x %lu", _r->offset ); | |||
| asprintf( &sa[i++], ":tempo %.2f", _tempo ); | |||
| sa[i] = NULL; | |||
| return sa; | |||
| } | |||
| void | |||
| set ( char **sa ) | |||
| { | |||
| for ( int i = 0; sa[i]; ++i ) | |||
| { | |||
| char *s = sa[i]; | |||
| strtok( s, " " ); | |||
| char *v = s + strlen( s ) + 1; | |||
| if ( ! strcmp( s, ":x" ) ) | |||
| _r->offset = atol( v ); | |||
| else | |||
| if ( ! strcmp( s, ":tempo" ) ) | |||
| _tempo = atof( v ); | |||
| else | |||
| if ( ! strcmp( s, ":track" ) ) | |||
| { | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Track *t = (Track*)Loggable::find( i ); | |||
| assert( t ); | |||
| t->add( this ); | |||
| } | |||
| free( s ); | |||
| } | |||
| free( sa ); | |||
| timeline->redraw(); | |||
| _make_label(); | |||
| } | |||
| char ** get ( void ); | |||
| void set ( char **sa ); | |||
| Tempo_Point ( ) | |||
| { | |||
| } | |||
| public: | |||
| /* for loggable */ | |||
| static Loggable * | |||
| create ( char **sa ) | |||
| { | |||
| Tempo_Point *r = new Tempo_Point; | |||
| static Loggable * create ( char **sa ); | |||
| r->set( sa ); | |||
| Tempo_Point ( nframes_t when, float bpm ); | |||
| return (Loggable *)r; | |||
| } | |||
| Tempo_Point ( nframes_t when, float bpm ) | |||
| { | |||
| _tempo = bpm; | |||
| _r->offset = when; | |||
| _make_label(); | |||
| log_create(); | |||
| } | |||
| ~Tempo_Point ( ); | |||
| Tempo_Point ( const Tempo_Point &rhs ) | |||
| { | |||
| @@ -134,27 +65,11 @@ public: | |||
| return new Tempo_Point( *(Tempo_Point*)r ); | |||
| } | |||
| ~Tempo_Point ( ) | |||
| { | |||
| if ( _label ) delete[] _label; | |||
| log_destroy(); | |||
| } | |||
| float tempo ( void ) const { return _tempo; } | |||
| void tempo ( float v ) { _tempo = v; } | |||
| int | |||
| handle ( int m ) | |||
| { | |||
| int r = Track_Widget::handle( m ); | |||
| if ( m == FL_RELEASE ) | |||
| { | |||
| _track->sort(); | |||
| timeline->redraw(); | |||
| } | |||
| return r; | |||
| } | |||
| float tempo ( void ) const | |||
| { return _tempo; } | |||
| void tempo ( float v ) | |||
| { _tempo = v; } | |||
| int handle ( int m ); | |||
| }; | |||
| #undef __CLASS__ | |||
| @@ -23,7 +23,6 @@ | |||
| #include "Tempo_Point.H" | |||
| #include <list> | |||
| using std::list; | |||
| class Tempo_Track : public Track | |||
| { | |||
| @@ -40,7 +39,7 @@ public: | |||
| { | |||
| // sort(); | |||
| for ( list <Track_Widget *>::const_reverse_iterator i = _widgets.rbegin(); | |||
| for ( std::list <Track_Widget *>::const_reverse_iterator i = _widgets.rbegin(); | |||
| i != _widgets.rend(); i++ ) | |||
| { | |||
| if ( (*i)->offset() < when ) | |||
| @@ -0,0 +1,69 @@ | |||
| /*******************************************************************************/ | |||
| /* Copyright (C) 2008 Jonathan Moore Liles */ | |||
| /* */ | |||
| /* This program is free software; you can redistribute it and/or modify it */ | |||
| /* under the terms of the GNU General Public License as published by the */ | |||
| /* Free Software Foundation; either version 2 of the License, or (at your */ | |||
| /* option) any later version. */ | |||
| /* */ | |||
| /* This program is distributed in the hope that it will be useful, but WITHOUT */ | |||
| /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ | |||
| /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ | |||
| /* more details. */ | |||
| /* */ | |||
| /* You should have received a copy of the GNU General Public License along */ | |||
| /* with This program; see the file COPYING. If not,write to the Free Software */ | |||
| /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |||
| /*******************************************************************************/ | |||
| #include "Time_Point.H" | |||
| #include "Time_Track.H" | |||
| #include "Timeline.H" // for timeline->time_track | |||
| char ** | |||
| Time_Point::get ( void ) | |||
| { | |||
| char **sa = (char**)malloc( sizeof( char* ) * 5 ); | |||
| int i = 0; | |||
| asprintf( &sa[i++], ":x %lu", _r->offset ); | |||
| asprintf( &sa[i++], ":beats_per_bar %d", _time.beats_per_bar ); | |||
| asprintf( &sa[i++], ":beat_type %d", _time.beat_type ); | |||
| sa[i] = NULL; | |||
| return sa; | |||
| } | |||
| void | |||
| Time_Point::set ( char **sa ) | |||
| { | |||
| for ( int i = 0; sa[i]; ++i ) | |||
| { | |||
| char *s = sa[i]; | |||
| strtok( s, " " ); | |||
| char *v = s + strlen( s ) + 1; | |||
| if ( ! strcmp( s, ":x" ) ) | |||
| _r->offset = atol( v ); | |||
| else if ( ! strcmp( s, ":beats_per_bar" ) ) | |||
| _time.beats_per_bar = atoi( v ); | |||
| else if ( ! strcmp( s, ":beat_type" ) ) | |||
| _time.beat_type = atoi( v ); | |||
| /* FIXME: we need to add this to the time track on creation!!! */ | |||
| timeline->time_track->add( this ); | |||
| free( s ); | |||
| } | |||
| free( sa ); | |||
| timeline->redraw(); | |||
| _make_label(); | |||
| } | |||
| @@ -65,63 +65,8 @@ protected: | |||
| const char *class_name ( void ) { return "Time_Point"; } | |||
| char ** get ( void ) | |||
| { | |||
| char **sa = (char**)malloc( sizeof( char* ) * 5 ); | |||
| int i = 0; | |||
| asprintf( &sa[i++], ":track 0x%X", _track ? _track->id() : 0 ); | |||
| asprintf( &sa[i++], ":x %lu", _r->offset ); | |||
| asprintf( &sa[i++], ":beats_per_bar %d", _time.beats_per_bar ); | |||
| asprintf( &sa[i++], ":beat_type %d", _time.beat_type ); | |||
| sa[i] = NULL; | |||
| return sa; | |||
| } | |||
| void | |||
| set ( char **sa ) | |||
| { | |||
| for ( int i = 0; sa[i]; ++i ) | |||
| { | |||
| char *s = sa[i]; | |||
| strtok( s, " " ); | |||
| char *v = s + strlen( s ) + 1; | |||
| if ( ! strcmp( s, ":x" ) ) | |||
| _r->offset = atol( v ); | |||
| else | |||
| if ( ! strcmp( s, ":beats_per_bar" ) ) | |||
| _time.beats_per_bar = atoi( v ); | |||
| else | |||
| if ( ! strcmp( s, ":beat_type" ) ) | |||
| _time.beat_type = atoi( v ); | |||
| else | |||
| if ( ! strcmp( s, ":track" ) ) | |||
| { | |||
| int i; | |||
| sscanf( v, "%X", &i ); | |||
| Track *t = (Track*)Loggable::find( i ); | |||
| assert( t ); | |||
| t->add( this ); | |||
| } | |||
| free( s ); | |||
| } | |||
| free( sa ); | |||
| timeline->redraw(); | |||
| _make_label(); | |||
| } | |||
| char ** get ( void ); | |||
| void set ( char **sa ); | |||
| public: | |||
| @@ -178,18 +178,18 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi | |||
| o->type( Fl_Pack::VERTICAL ); | |||
| o->spacing( 0 ); | |||
| for ( int i = 1; i--; ) | |||
| { | |||
| // Track_Header *t = new Track_Header( 0, 0, W, 75 ); | |||
| Track_Header *t = new Track_Header( 0, 0, W, 30 ); | |||
| Track *o = new Audio_Track( 0, 0, 1, 100 ); | |||
| t->track( o ); | |||
| t->add( new Audio_Track( 0, 0, 1, 100 ) ); | |||
| t->add( new Audio_Track( 0, 0, 1, 100 ) ); | |||
| t->add_control( new Control_Track( 0, 0, 1, 100 ) ); | |||
| t->color( (Fl_Color)rand() ); | |||
| } | |||
| /* for ( int i = 1; i--; ) */ | |||
| /* { */ | |||
| /* // Track_Header *t = new Track_Header( 0, 0, W, 75 ); */ | |||
| /* Track_Header *t = new Track_Header( 0, 0, W, 30 ); */ | |||
| /* Track *o = new Audio_Track( 0, 0, 1, 100 ); */ | |||
| /* t->track( o ); */ | |||
| /* t->add( new Audio_Track( 0, 0, 1, 100 ) ); */ | |||
| /* t->add( new Audio_Track( 0, 0, 1, 100 ) ); */ | |||
| /* t->add_control( new Control_Track( 0, 0, 1, 100 ) ); */ | |||
| /* t->color( (Fl_Color)rand() ); */ | |||
| /* } */ | |||
| tracks = o; | |||
| o->end(); | |||
| @@ -443,12 +443,20 @@ Timeline::draw ( void ) | |||
| { | |||
| int X, Y, W, H; | |||
| X = tracks->x() + Fl::box_dx( tracks->child( 0 )->box() ) + 1; | |||
| Y = tracks->y(); | |||
| W = tracks->w() - Fl::box_dw( tracks->child( 0 )->box() ) - 1; | |||
| H = tracks->h(); | |||
| int bdx = 0; | |||
| int bdw = 0; | |||
| /* FIXME: hack to avoid clobbering the box corners of tracks. */ | |||
| if ( tracks->children() ) | |||
| { | |||
| bdx = Fl::box_dx( tracks->child( 0 )->box() ); | |||
| bdw = Fl::box_dw( tracks->child( 0 )->box() ); | |||
| } | |||
| X = tracks->x() + bdx + 1; | |||
| Y = tracks->y(); | |||
| W = tracks->w() - bdw - 1; | |||
| H = tracks->h(); | |||
| /* if ( damage() & FL_DAMAGE_USER1 ) */ | |||
| /* { */ | |||
| @@ -46,8 +46,8 @@ class Tempo_Track; | |||
| class Time_Track; | |||
| class Ruler_Track; | |||
| #include <list> | |||
| using std::list; | |||
| /* #include <list> */ | |||
| /* using std::list; */ | |||
| // disables double-buffering to make unnecessary redrawing more apparent | |||
| @@ -105,10 +105,6 @@ class Timeline : public Fl_Overlay_Window, public RWLock | |||
| Scalebar *hscroll; | |||
| Fl_Scrollbar *vscroll; | |||
| Tempo_Track *tempo_track; | |||
| Time_Track *time_track; | |||
| Ruler_Track *ruler_track; | |||
| static void cb_scroll ( Fl_Widget *w, void *v ); | |||
| void cb_scroll ( Fl_Widget *w ); | |||
| @@ -120,6 +116,11 @@ class Timeline : public Fl_Overlay_Window, public RWLock | |||
| public: | |||
| Tempo_Track *tempo_track; | |||
| Time_Track *time_track; | |||
| Ruler_Track *ruler_track; | |||
| nframes_t xoffset; | |||
| int _yposition; | |||
| @@ -72,7 +72,6 @@ main ( int argc, char **argv ) | |||
| Fl::scheme( "plastic" ); | |||
| // Fl::scheme( "gtk+" ); | |||
| Loggable::open( "history" ); | |||
| /* welcome to C++ */ | |||
| Loggable::register_create( "Region", &Region::create ); | |||
| Loggable::register_create( "Tempo_Point", &Tempo_Point::create ); | |||
| @@ -80,12 +79,16 @@ main ( int argc, char **argv ) | |||
| Loggable::register_create( "Control_Point", &Control_Point::create ); | |||
| Loggable::register_create( "Track_Header", &Track_Header::create ); | |||
| /* TODO: change to seesion dir */ | |||
| /* we don't really need a pointer for this */ | |||
| engine = new Engine; | |||
| engine->init(); | |||
| timeline = new Timeline( 0, 24, main_window->w(), main_window->h() - 24, "Timeline" ); | |||
| Loggable::open( "history" ); | |||
| Fl_Button *o = new Fl_Button( 0, 0, 50, 24, "undo" ); | |||
| o->shortcut( FL_CTRL + 'z' ); | |||
| o->callback( cb_undo, 0 ); | |||