Browse Source

Attempt to draw measure lines with a more efficient incremental algorithm.

tags/non-daw-v1.1.0
Jonathan Moore Liles 17 years ago
parent
commit
34400df589
6 changed files with 127 additions and 26 deletions
  1. +1
    -1
      Timeline/Region.C
  2. +1
    -0
      Timeline/Sequence.H
  3. +19
    -7
      Timeline/Tempo_Sequence.H
  4. +23
    -12
      Timeline/Time_Point.H
  5. +82
    -6
      Timeline/Timeline.C
  6. +1
    -0
      Timeline/Timeline.H

+ 1
- 1
Timeline/Region.C View File

@@ -712,7 +712,7 @@ Region::draw ( void )
} }


/* FIXME: only draw as many as are necessary! */ /* FIXME: only draw as many as are necessary! */
timeline->draw_measure_lines( rx, Y, rw, H, _box_color );
timeline->draw_measure_lines( X, Y, W, H, _box_color );


/* fl_color( FL_BLACK ); */ /* fl_color( FL_BLACK ); */
/* fl_line( rx, Y, rx, Y + H ); */ /* fl_line( rx, Y, rx, Y + H ); */


+ 1
- 0
Timeline/Sequence.H View File

@@ -49,6 +49,7 @@ protected:


char *_name; char *_name;


friend class Timeline; // for draw_measure
std::list <Sequence_Widget *> _widgets; std::list <Sequence_Widget *> _widgets;
Sequence_Widget *event_widget ( void ); Sequence_Widget *event_widget ( void );




+ 19
- 7
Timeline/Tempo_Sequence.H View File

@@ -34,25 +34,37 @@ public:
// box( FL_DOWN_BOX ); // box( FL_DOWN_BOX );
} }



/** return a pointer to the closest tempo point *before* /when/ */
Tempo_Point *
at ( nframes_t when )
{
for ( std::list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin();
i != _widgets.rend(); i++ )
if ( (*i)->offset() < when )
return ((Tempo_Point*)(*i));

return NULL;
}

float float
beats_per_minute ( nframes_t when ) beats_per_minute ( nframes_t when )
{ {
// sort(); // sort();


for ( std::list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin();
i != _widgets.rend(); i++ )
{
if ( (*i)->offset() < when )
return ((Tempo_Point*)(*i))->tempo();
}
Tempo_Point *p = at( when );


return 120.0;
if ( p )
return p->tempo();
else
return 120.0;
} }


void void
beats_per_minute ( nframes_t when, float bpm ) beats_per_minute ( nframes_t when, float bpm )
{ {
add( new Tempo_Point( when, bpm ) ); add( new Tempo_Point( when, bpm ) );
sort();
} }


}; };

+ 23
- 12
Timeline/Time_Point.H View File

@@ -104,18 +104,29 @@ public:
void time ( int bpb, int note ) { _time.beats_per_bar = bpb; _time.beat_type = note; } void time ( int bpb, int note ) { _time.beats_per_bar = bpb; _time.beat_type = note; }
time_sig time ( void ) const { return _time; } time_sig time ( void ) const { return _time; }


int
handle ( int m )
{
int r = Sequence_Widget::handle( m );

if ( m == FL_RELEASE )
{
_track->sort();
timeline->redraw();
}
return r;
}
/* Time_Point * */
/* at ( nframes_t when ) */
/* { */
/* for ( std::list <Sequence_Widget *>::const_reverse_iterator i = _widgets.rbegin(); */
/* i != _widgets.rend(); i++ ) */
/* if ( (*i)->offset() < when ) */
/* return ((Time_Point*)(*i)); */

/* return NULL; */
/* } */

/* int */
/* handle ( int m ) */
/* { */
/* int r = Sequence_Widget::handle( m ); */

/* if ( m == FL_RELEASE ) */
/* { */
/* _track->sort(); */
/* timeline->redraw(); */
/* } */
/* return r; */
/* } */


}; };




+ 82
- 6
Timeline/Timeline.C View File

@@ -151,6 +151,12 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
o->align( FL_ALIGN_LEFT ); o->align( FL_ALIGN_LEFT );


tempo_track = o; tempo_track = o;

o->beats_per_minute( 0, 120 );

o->beats_per_minute( 48000 * 50, 250 );

o->beats_per_minute( 48000 * 120, 60 );
} }


{ {
@@ -162,6 +168,8 @@ Timeline::Timeline ( int X, int Y, int W, int H, const char* L ) : Fl_Overlay_Wi
o->align( FL_ALIGN_LEFT ); o->align( FL_ALIGN_LEFT );


time_track = o; time_track = o;

o->time( 0, 4, 4 );
} }


{ {
@@ -306,6 +314,12 @@ Timeline::nearest_line ( int ix )
return -1; return -1;
} }


nframes_t
Timeline::x_to_offset ( int x ) const
{
return x_to_ts( max( 0, x - Track::width() ) ) + xoffset;
}

/** draw appropriate measure lines inside the given bounding box */ /** draw appropriate measure lines inside the given bounding box */
/* FIXME: this function *really* needs to be optimized. Currently it /* FIXME: this function *really* needs to be optimized. Currently it
searched both the time and tempo lists once for every horiontal searched both the time and tempo lists once for every horiontal
@@ -316,23 +330,83 @@ Timeline::draw_measure ( int X, int Y, int W, int H, Fl_Color color, bool BBT )
if ( ! draw_with_measure_lines ) if ( ! draw_with_measure_lines )
return; return;


fl_push_clip( X, Y, W, H );
// fl_push_clip( X, Y, W, H );


// fl_line_style( FL_DASH, 2 ); // fl_line_style( FL_DASH, 2 );
fl_line_style( FL_DASH, 0 ); fl_line_style( FL_DASH, 0 );


const Fl_Color beat = fl_color_average( FL_BLACK, color, 0.65f ); const Fl_Color beat = fl_color_average( FL_BLACK, color, 0.65f );
const Fl_Color bar = fl_color_average( FL_RED, color, 0.65f );
const Fl_Color bar = fl_color_average( FL_RED, beat, 0.65f );


const nframes_t samples_per_minute = sample_rate() * 60; const nframes_t samples_per_minute = sample_rate() * 60;


/* we need to back up a bit in order to catch all the numbers */ /* we need to back up a bit in order to catch all the numbers */
if ( BBT )

/* if ( BBT ) */
/* { */
/* X -= 40; */
/* W += 40; */
/* } */

nframes_t when = x_to_offset( X );

list <Sequence_Widget*>::const_iterator tpi;
list <Sequence_Widget*>::const_iterator mpi;

/* find the first points before our range */

for ( list <Sequence_Widget *>::const_reverse_iterator i = tempo_track->_widgets.rbegin();
i != tempo_track->_widgets.rend(); i++ )
if ( (*i)->offset() <= when )
{
tpi = i.base();
break;
}

for ( list <Sequence_Widget *>::const_reverse_iterator i = time_track->_widgets.rbegin();
i != time_track->_widgets.rend(); i++ )
if ( (*i)->offset() <= when )
{
mpi = i.base();
break;
}

--tpi;

/* start on the next beat */
const Tempo_Point *tp = (Tempo_Point*)(*tpi);
nframes_t beat_inc = samples_per_minute / tp->tempo();

nframes_t f = when - ( ( when - tp->offset() ) % beat_inc );

for ( ; tpi != tempo_track->_widgets.end(); ++tpi )
{ {
X -= 40;
W += 40;
list <Sequence_Widget*>::const_iterator ntpi = tpi;
++ntpi;

tp = (Tempo_Point*)(*tpi);
const Tempo_Point *ntp = (Tempo_Point*)(*ntpi);

const nframes_t ntpo = ntp ? ntp->offset() : when + x_to_ts( W + 1 );

beat_inc = samples_per_minute / tp->tempo();

const int incx = ts_to_x( beat_inc );

if ( incx < 8 )
continue;

for ( ; f < ntpo; f += beat_inc )
{
const int x = ts_to_x( f - xoffset ) + Track::width();

fl_color( beat );

fl_line( x, Y, x, Y + H );
}
} }


#if 0
for ( int x = X; x < X + W; ++x ) for ( int x = X; x < X + W; ++x )
{ {
// measure = ts_to_x( (double)(sample_rate() * 60) / beats_per_minute( x_to_ts( x - Track::width() ) + xoffset ) ); // measure = ts_to_x( (double)(sample_rate() * 60) / beats_per_minute( x_to_ts( x - Track::width() ) + xoffset ) );
@@ -404,9 +478,11 @@ Timeline::draw_measure ( int X, int Y, int W, int H, Fl_Color color, bool BBT )


} }


#endif

fl_line_style( FL_SOLID, 0 ); fl_line_style( FL_SOLID, 0 );


fl_pop_clip();
// fl_pop_clip();
} }


void void


+ 1
- 0
Timeline/Timeline.H View File

@@ -135,6 +135,7 @@ public:
nframes_t sample_rate ( void ) const { return engine->sample_rate(); } nframes_t sample_rate ( void ) const { return engine->sample_rate(); }
int ts_to_x( nframes_t ts ) const { return ts >> _fpp; } int ts_to_x( nframes_t ts ) const { return ts >> _fpp; }
nframes_t x_to_ts ( int x ) const { return x << _fpp; } nframes_t x_to_ts ( int x ) const { return x << _fpp; }
nframes_t x_to_offset ( int x ) const;


float beats_per_minute ( nframes_t when ) const; float beats_per_minute ( nframes_t when ) const;
int beats_per_bar ( nframes_t when ) const; int beats_per_bar ( nframes_t when ) const;


Loading…
Cancel
Save