Work on actually rendering tempo map into BBT info.

This commit is contained in:
Jonathan Moore Liles 2008-05-13 00:39:29 -05:00
parent 30b4c1bb4b
commit d4d5c17e44
6 changed files with 168 additions and 51 deletions

View File

@ -32,6 +32,7 @@ const float CLOCK_UPDATE_FREQ = 0.06f;
/* TODO: frames per second? */ /* TODO: frames per second? */
#include "Sequence_Widget.H"
class Clock : public Fl_Widget class Clock : public Fl_Widget
{ {
@ -93,7 +94,9 @@ public:
static void static void
frame_to_BBT ( char *dst, int n, nframes_t frame ) frame_to_BBT ( char *dst, int n, nframes_t frame )
{ {
snprintf( dst, n, "unimplemented" ); struct BBT bbt = timeline->solve_tempomap( frame );
snprintf( dst, n, "%03d:%1d:%04d", bbt.bar + 1, bbt.beat + 1 , bbt.tick );
} }

View File

@ -61,6 +61,10 @@ struct Range
{ {
length += n; length += n;
} }
Range ( ) : start( 0 ), offset( 0 ), length( 0 )
{
}
}; };
/* Used by time/tempo points or any other child of Sequence_Widget /* Used by time/tempo points or any other child of Sequence_Widget
@ -71,6 +75,10 @@ struct BBT
unsigned short bar; unsigned short bar;
unsigned char beat; unsigned char beat;
unsigned short tick; unsigned short tick;
BBT ( ) : bar( 0 ), beat( 0 ), tick( 0 )
{
}
}; };
@ -242,31 +250,31 @@ public:
_drag = NULL; _drag = NULL;
} }
void /* void */
start ( nframes_t where ) /* start ( nframes_t where ) */
{ /* { */
if ( ! selected() ) /* if ( ! selected() ) */
{ /* { */
redraw(); /* redraw(); */
_r->start = where; /* _r->start = where; */
} /* } */
else /* else */
{ /* { */
long d = where - _r->start; /* long d = where - _r->start; */
for ( list <Sequence_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ ) /* for ( list <Sequence_Widget *>::iterator i = _selection.begin(); i != _selection.end(); i++ ) */
{ /* { */
(*i)->redraw(); /* (*i)->redraw(); */
if ( d < 0 ) /* if ( d < 0 ) */
(*i)->_r->start -= 0 - d; /* (*i)->_r->start -= 0 - d; */
else /* else */
(*i)->_r->start += d; /* (*i)->_r->start += d; */
} /* } */
} /* } */
} /* } */
int dispatch ( int m ); int dispatch ( int m );
@ -317,7 +325,7 @@ public:
void sequence ( Sequence *t ) { _sequence = t; } void sequence ( Sequence *t ) { _sequence = t; }
nframes_t start ( void ) const { return _r->start; } nframes_t start ( void ) const { return _r->start; }
// void start ( nframes_t o ) { _r->start = o; } void start ( nframes_t o ) { _r->start = o; }
void length ( nframes_t v ) { _r->length = v; } void length ( nframes_t v ) { _r->length = v; }
virtual nframes_t length ( void ) const { return _r->length; } virtual nframes_t length ( void ) const { return _r->length; }

View File

@ -26,6 +26,8 @@ class Tempo_Point : public Sequence_Point
{ {
float _tempo; float _tempo;
BBT _bbt;
void void
_make_label ( void ) _make_label ( void )
{ {
@ -51,6 +53,8 @@ public:
static bool edit ( float *tempo ); static bool edit ( float *tempo );
const BBT * bbt ( void ) const { return &_bbt; }
Tempo_Point ( nframes_t when, float bpm ); Tempo_Point ( nframes_t when, float bpm );
~Tempo_Point ( ); ~Tempo_Point ( );
@ -58,6 +62,7 @@ public:
Tempo_Point ( const Tempo_Point &rhs ) : Sequence_Point( rhs ) Tempo_Point ( const Tempo_Point &rhs ) : Sequence_Point( rhs )
{ {
_tempo = rhs._tempo; _tempo = rhs._tempo;
_bbt = rhs._bbt;
log_create(); log_create();
} }

View File

@ -27,16 +27,12 @@ struct time_sig
int beats_per_bar; int beats_per_bar;
int beat_type; int beat_type;
time_sig ( ) time_sig ( ) : beats_per_bar( 0 ), beat_type( 0 )
{ {
beats_per_bar = 0;
beat_type = 0;
} }
time_sig ( int bpb, int note ) time_sig ( int bpb, int note ) : beats_per_bar( bpb ), beat_type( note )
{ {
beats_per_bar = bpb;
beat_type = note;
} }
}; };

View File

@ -313,10 +313,9 @@ Timeline::nearest_line ( nframes_t when, nframes_t *frame ) const
nearest_line_arg n = { when, -1 }; nearest_line_arg n = { when, -1 };
/* FIXME: handle snap to bar */ /* FIXME: handle snap to bar */
draw_measure( when - x_to_ts( 10 ), 0, 20, 0, (Fl_Color)0, nearest_line_cb, &n, false ); draw_measure( when - x_to_ts( 10 ), 0, 20, 0, (Fl_Color)0, nearest_line_cb, frame );
*frame = n.closest; *frame = n.closest;
return *frame != (nframes_t)-1; return *frame != (nframes_t)-1;
} }
@ -340,9 +339,102 @@ draw_measure_cb ( nframes_t frame, int X, int Y, int H, void *arg )
fl_line( X, Y, X, Y + H ); fl_line( X, Y, X, Y + H );
} }
#if 0
/* we cache measure lines by rendering them to these structures. */
struct Measure_Line
{
/* it's easier to use this than a pixel coord, because the snapping
* code requires a frame number to be precise. */
nframes_t frame;
bool bar; /* is this a bar line, or just a beat? */
};
#endif
BBT
Timeline::solve_tempomap ( nframes_t when )
{
/* if ( ! tempo_track->_widgets.size() || ! time_track->_widgets.size() ) */
/* { */
/* DWARNING( "No tempo/time points" ); */
/* return; */
/* } */
const nframes_t samples_per_minute = sample_rate() * 60;
list <Sequence_Widget*> tempo_map;
/* merge time and tempo maps into one list for convenience */
for ( list <Sequence_Widget *>::iterator i = tempo_track->_widgets.begin();
i != tempo_track->_widgets.end(); ++i )
tempo_map.push_back( *i );
for ( list <Sequence_Widget *>::iterator i = time_track->_widgets.begin();
i != time_track->_widgets.end(); ++i )
tempo_map.push_back( *i );
tempo_map.sort( Sequence_Widget::sort_func );
float bpm = 120.0f;
time_sig sig;
sig.beats_per_bar = 4;
sig.beat_type = 4;
BBT bbt;
nframes_t f = 0;
nframes_t beat_inc = samples_per_minute / bpm;
for ( list <Sequence_Widget *>::iterator i = tempo_map.begin();
i != tempo_map.end(); ++i )
{
nframes_t next;
{
list <Sequence_Widget *>::iterator n = i;
++n;
next = n != tempo_map.end() ? (*n)->start() : when;
}
if ( ! strcmp( (*i)->class_name(), "Tempo_Point" ) )
{
const Tempo_Point *p = (Tempo_Point*)(*i);
bpm = p->tempo();
beat_inc = samples_per_minute / bpm;
}
else
{
const Time_Point *p = (Time_Point*)(*i);
sig = p->time();
}
for ( ; f < next; f += beat_inc )
{
if ( ++bbt.beat == sig.beats_per_bar )
{
bbt.beat = 0;
++bbt.bar;
}
}
// const int x = ts_to_x( f - xoffset ) + Track::width();
if ( f >= when )
return bbt;
}
}
/** draw appropriate measure lines inside the given bounding box */ /** draw appropriate measure lines inside the given bounding box */
void void
Timeline::draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, measure_line_callback * cb, void *arg, bool BBT ) const Timeline::draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, measure_line_callback * cb, void *arg ) const
{ {
if ( ! draw_with_measure_lines ) if ( ! draw_with_measure_lines )
return; return;
@ -368,35 +460,39 @@ Timeline::draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, me
/* W += 40; */ /* W += 40; */
/* } */ /* } */
list <Sequence_Widget*>::const_iterator tpi;
list <Sequence_Widget*>::const_iterator mpi; list <Sequence_Widget*>::const_iterator mpi;
/* find the first points before our range */ /* find the first points before our range */
for ( list <Sequence_Widget *>::const_reverse_iterator i = tempo_track->_widgets.rbegin(); /* for ( list <Sequence_Widget *>::const_reverse_iterator i = tempo_track->_widgets.rbegin(); */
i != tempo_track->_widgets.rend(); i++ ) /* i != tempo_track->_widgets.rend(); i++ ) */
if ( (*i)->start() <= when ) /* if ( (*i)->start() <= when ) */
{ /* { */
tpi = i.base(); /* tpi = i.base(); */
break; /* break; */
} /* } */
for ( list <Sequence_Widget *>::const_reverse_iterator i = time_track->_widgets.rbegin(); /* for ( list <Sequence_Widget *>::const_reverse_iterator i = time_track->_widgets.rbegin(); */
i != time_track->_widgets.rend(); i++ ) /* i != time_track->_widgets.rend(); i++ ) */
if ( (*i)->start() <= when ) /* if ( (*i)->start() <= when ) */
{ /* { */
mpi = i.base(); /* mpi = i.base(); */
break; /* break; */
} /* } */
--tpi; /* --tpi; */
/* start from the beginnnig */
/* FIXME: find a closer place to start */
list <Sequence_Widget *>::const_iterator tpi = tempo_track->_widgets.begin();
/* start on the next beat */ /* start on the next beat */
const Tempo_Point *tp = (Tempo_Point*)(*tpi); const Tempo_Point *tp = (Tempo_Point*)(*tpi);
nframes_t beat_inc = samples_per_minute / tp->tempo(); nframes_t beat_inc = samples_per_minute / tp->tempo();
nframes_t f = when - ( ( when - tp->start() ) % beat_inc ); nframes_t f = 0;
/* nframes_t f = when - ( ( when - tp->start() ) % beat_inc ); */
for ( ; tpi != tempo_track->_widgets.end(); ++tpi ) for ( ; tpi != tempo_track->_widgets.end(); ++tpi )
{ {
@ -422,6 +518,13 @@ Timeline::draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, me
const int x = ts_to_x( f - xoffset ) + Track::width(); const int x = ts_to_x( f - xoffset ) + Track::width();
cb( f, x, Y, H, arg ); cb( f, x, Y, H, arg );
/* BBT bbt; */
/* bbt = const_cast< Timeline* >(this)->solve_tempomap( f ); */
/* printf( "%d:%d:%d\n", bbt.bar, bbt.beat, bbt.tick ); */
} }
} }
@ -431,7 +534,7 @@ Timeline::draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, me
void void
Timeline::draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color ) Timeline::draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color )
{ {
draw_measure( x_to_offset( X ), Y, W, H, color, draw_measure_cb, 0, false ); draw_measure( x_to_offset( X ), Y, W, H, color, draw_measure_cb, 0 );
} }
/** just like draw mesure lines except that it also draws the BBT values. */ /** just like draw mesure lines except that it also draws the BBT values. */

View File

@ -42,6 +42,7 @@ extern Timeline *timeline;
#include "Sequence.H" #include "Sequence.H"
struct BBT;
class Tempo_Sequence; class Tempo_Sequence;
class Time_Sequence; class Time_Sequence;
class Annotation_Sequence; class Annotation_Sequence;
@ -149,9 +150,10 @@ public:
typedef void (measure_line_callback)( nframes_t frame, int X, int Y, int H, void *arg ); typedef void (measure_line_callback)( nframes_t frame, int X, int Y, int H, void *arg );
BBT solve_tempomap ( nframes_t when );
void draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color ); void draw_measure_lines ( int X, int Y, int W, int H, Fl_Color color );
void draw_measure_BBT ( int X, int Y, int W, int H, Fl_Color color ); void draw_measure_BBT ( int X, int Y, int W, int H, Fl_Color color );
void draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, measure_line_callback *cb, void *arg, bool BBT ) const; void draw_measure ( nframes_t when, int Y, int W, int H, Fl_Color color, measure_line_callback *cb, void *arg ) const;
void xposition ( int X ); void xposition ( int X );
void yposition ( int Y ); void yposition ( int Y );