| @@ -44,6 +44,21 @@ Loggable::open ( const char *filename ) | |||||
| return false; | 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; | return true; | ||||
| } | } | ||||
| @@ -116,7 +131,9 @@ bool | |||||
| Loggable::do_this ( const char *s, bool reverse ) | Loggable::do_this ( const char *s, bool reverse ) | ||||
| { | { | ||||
| int id; | int id; | ||||
| sscanf( s, "%*s %X ", &id ); | |||||
| if ( ! ( sscanf( s, "%*s %X ", &id ) > 0 ) ) | |||||
| return false; | |||||
| Loggable *l = find( id ); | Loggable *l = find( id ); | ||||
| // assert( l ); | // assert( l ); | ||||
| @@ -328,6 +345,19 @@ Loggable::log ( const char *fmt, ... ) | |||||
| void | void | ||||
| Loggable::flush ( 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(); | int n = _transaction.size(); | ||||
| if ( n > 1 ) | if ( n > 1 ) | ||||
| @@ -128,6 +128,9 @@ public: | |||||
| _id = id; | _id = id; | ||||
| /* make sure it'll fit */ | |||||
| _loggables.reserve( _id ); | |||||
| assert( ! _loggables[ _id - 1 ] ); | assert( ! _loggables[ _id - 1 ] ); | ||||
| _loggables[ _id - 1 ] = this; | _loggables[ _id - 1 ] = this; | ||||
| @@ -8,6 +8,8 @@ SRCS= \ | |||||
| Timeline.C \ | Timeline.C \ | ||||
| Track_Header.C \ | Track_Header.C \ | ||||
| Track_Widget.C \ | Track_Widget.C \ | ||||
| Tempo_Point.C \ | |||||
| Time_Point.C \ | |||||
| Peaks.C \ | Peaks.C \ | ||||
| Audio_File.C \ | Audio_File.C \ | ||||
| Audio_File_SF.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 | #pragma once | ||||
| #include "Track_Point.H" | #include "Track_Point.H" | ||||
| #define __CLASS__ "Tempo_Point" | |||||
| // #include "Tempo_Track.H" | |||||
| class Tempo_Point : public Track_Point | class Tempo_Point : public Track_Point | ||||
| { | { | ||||
| @@ -40,88 +39,20 @@ protected: | |||||
| const char *class_name ( void ) { return "Tempo_Point"; } | 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 ( ) | Tempo_Point ( ) | ||||
| { | { | ||||
| } | } | ||||
| public: | 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 ) | Tempo_Point ( const Tempo_Point &rhs ) | ||||
| { | { | ||||
| @@ -134,27 +65,11 @@ public: | |||||
| return new Tempo_Point( *(Tempo_Point*)r ); | 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 "Tempo_Point.H" | ||||
| #include <list> | #include <list> | ||||
| using std::list; | |||||
| class Tempo_Track : public Track | class Tempo_Track : public Track | ||||
| { | { | ||||
| @@ -40,7 +39,7 @@ public: | |||||
| { | { | ||||
| // sort(); | // 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++ ) | i != _widgets.rend(); i++ ) | ||||
| { | { | ||||
| if ( (*i)->offset() < when ) | 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"; } | 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: | 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->type( Fl_Pack::VERTICAL ); | ||||
| o->spacing( 0 ); | 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; | tracks = o; | ||||
| o->end(); | o->end(); | ||||
| @@ -443,12 +443,20 @@ Timeline::draw ( void ) | |||||
| { | { | ||||
| int X, Y, W, H; | 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 ) */ | /* if ( damage() & FL_DAMAGE_USER1 ) */ | ||||
| /* { */ | /* { */ | ||||
| @@ -46,8 +46,8 @@ class Tempo_Track; | |||||
| class Time_Track; | class Time_Track; | ||||
| class Ruler_Track; | class Ruler_Track; | ||||
| #include <list> | |||||
| using std::list; | |||||
| /* #include <list> */ | |||||
| /* using std::list; */ | |||||
| // disables double-buffering to make unnecessary redrawing more apparent | // disables double-buffering to make unnecessary redrawing more apparent | ||||
| @@ -105,10 +105,6 @@ class Timeline : public Fl_Overlay_Window, public RWLock | |||||
| Scalebar *hscroll; | Scalebar *hscroll; | ||||
| Fl_Scrollbar *vscroll; | Fl_Scrollbar *vscroll; | ||||
| Tempo_Track *tempo_track; | |||||
| Time_Track *time_track; | |||||
| Ruler_Track *ruler_track; | |||||
| static void cb_scroll ( Fl_Widget *w, void *v ); | static void cb_scroll ( Fl_Widget *w, void *v ); | ||||
| void cb_scroll ( Fl_Widget *w ); | void cb_scroll ( Fl_Widget *w ); | ||||
| @@ -120,6 +116,11 @@ class Timeline : public Fl_Overlay_Window, public RWLock | |||||
| public: | public: | ||||
| Tempo_Track *tempo_track; | |||||
| Time_Track *time_track; | |||||
| Ruler_Track *ruler_track; | |||||
| nframes_t xoffset; | nframes_t xoffset; | ||||
| int _yposition; | int _yposition; | ||||
| @@ -72,7 +72,6 @@ main ( int argc, char **argv ) | |||||
| Fl::scheme( "plastic" ); | Fl::scheme( "plastic" ); | ||||
| // Fl::scheme( "gtk+" ); | // Fl::scheme( "gtk+" ); | ||||
| Loggable::open( "history" ); | |||||
| /* welcome to C++ */ | /* welcome to C++ */ | ||||
| Loggable::register_create( "Region", &Region::create ); | Loggable::register_create( "Region", &Region::create ); | ||||
| Loggable::register_create( "Tempo_Point", &Tempo_Point::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( "Control_Point", &Control_Point::create ); | ||||
| Loggable::register_create( "Track_Header", &Track_Header::create ); | Loggable::register_create( "Track_Header", &Track_Header::create ); | ||||
| /* TODO: change to seesion dir */ | |||||
| /* we don't really need a pointer for this */ | /* we don't really need a pointer for this */ | ||||
| engine = new Engine; | engine = new Engine; | ||||
| engine->init(); | engine->init(); | ||||
| timeline = new Timeline( 0, 24, main_window->w(), main_window->h() - 24, "Timeline" ); | 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" ); | Fl_Button *o = new Fl_Button( 0, 0, 50, 24, "undo" ); | ||||
| o->shortcut( FL_CTRL + 'z' ); | o->shortcut( FL_CTRL + 'z' ); | ||||
| o->callback( cb_undo, 0 ); | o->callback( cb_undo, 0 ); | ||||