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