From 8a467843d00260a249b5fa25bd7af90f9e965799 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sun, 9 Mar 2008 13:28:48 -0500 Subject: [PATCH] Draw crossfade waveforms in x-ray style. --- Region.C | 2 +- Track.C | 29 ++++++++-- Track_Widget.H | 1 + Waveform.C | 140 ++++++++++++++++++++++++++----------------------- Waveform.H | 13 ++++- 5 files changed, 113 insertions(+), 72 deletions(-) diff --git a/Region.C b/Region.C index ba31e35..2761b9f 100644 --- a/Region.C +++ b/Region.C @@ -459,7 +459,7 @@ Region::draw ( int X, int Y, int W, int H ) int ch = (h() - Fl::box_dh( box() )) / _clip->channels(); for ( int i = _clip->channels(); i--; ) - draw_waveform( rx, X, (y() + Fl::box_dy( box() )) + (i * ch), W, ch, _clip, i, timeline->fpp(), + Waveform::draw( rx, X, (y() + Fl::box_dy( box() )) + (i * ch), W, ch, _clip, i, timeline->fpp(), _start + offset, min( (_end - _start) - offset, _end), _scale, selected() ? fl_invert_color( _color ) : _color ); diff --git a/Track.C b/Track.C index 1e4bad2..f3fe725 100644 --- a/Track.C +++ b/Track.C @@ -49,6 +49,9 @@ Track::overlaps ( Track_Widget *r ) return NULL; } + +#include "Waveform.H" + void Track::draw ( void ) { @@ -69,6 +72,10 @@ Track::draw ( void ) for ( list ::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) (*r)->draw_box( X, Y, W, H ); + for ( list ::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) + (*r)->draw( X, Y, W, H ); + + /* draw crossfades */ for ( list ::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) { @@ -88,6 +95,25 @@ Track::draw ( void ) draw_box( FL_FLAT_BOX, b.x - 100, b.y, b.w + 200, b.h, c ); draw_box( FL_UP_FRAME, b.x - 100, b.y, b.w + 200, b.h, c ); + + /* draw overlapping waveforms in X-ray style. */ + Waveform::fill = false; + +/* Fl_Color oc = o->color(); */ +/* Fl_Color rc = (*r)->color(); */ + +/* /\* give each region a different color *\/ */ +/* o->color( FL_RED ); */ +/* (*r)->color( FL_GREEN ); */ + + o->draw( b.x, b.y, b.w, b.h ); + (*r)->draw( b.x, b.y, b.w, b.h ); + Waveform::fill = true; + + +/* o->color( oc ); */ +/* (*r)->color( rc ); */ + /* fl_color( FL_BLACK ); */ /* fl_line_style( FL_DOT, 4 ); */ @@ -106,9 +132,6 @@ Track::draw ( void ) } } - for ( list ::const_iterator r = _widgets.begin(); r != _widgets.end(); r++ ) - (*r)->draw( X, Y, W, H ); - timeline->draw_measure_lines( x(), y(), w(), h(), color() ); fl_pop_clip(); diff --git a/Track_Widget.H b/Track_Widget.H index e4687d5..3510176 100644 --- a/Track_Widget.H +++ b/Track_Widget.H @@ -173,6 +173,7 @@ public: virtual int abs_w ( void ) const { return timeline->ts_to_x( _end - _start ); } Fl_Color color ( void ) { return _color; } + void color ( Fl_Color v ) { _color = v; } Fl_Color box_color ( void ) { return _box_color; } Track * track ( void ) const { return _track; } diff --git a/Waveform.C b/Waveform.C index 0d12392..10d3323 100644 --- a/Waveform.C +++ b/Waveform.C @@ -26,55 +26,61 @@ #include "Timeline.H" #include "Audio_File.H" +#include "Waveform.H" #include -const bool outline = true; -const bool vary_color = true; + +bool Waveform::fill = true; +bool Waveform::outline = true; +bool Waveform::vary_color = true; + +/* TODO: split the variations into separate functions. eg, plain, + * outlined, filled, polygonal, rectified. */ /** draw a portion of /clip/'s waveform. coordinates are the portion to draw */ -void -draw_waveform ( int ox, int X, int Y, int W, int H, Audio_File *_clip, int channel, float fpp, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ) -{ - fl_push_clip( X, Y, W, H ); + void + Waveform::draw ( int ox, int X, int Y, int W, int H, Audio_File *_clip, int channel, float fpp, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ) + { + fl_push_clip( X, Y, W, H ); - int j; + int j; // int start = timeline->ts_to_x( _start ); - int start = timeline->ts_to_x( _start ) + (X - ox); + int start = timeline->ts_to_x( _start ) + (X - ox); - const Peaks *pk = _clip->peaks( channel ); + const Peaks *pk = _clip->peaks( channel ); - _start = timeline->x_to_ts( start ); + _start = timeline->x_to_ts( start ); - pk->fill_buffer( fpp, _start, _start + timeline->x_to_ts( W ) ); + pk->fill_buffer( fpp, _start, _start + timeline->x_to_ts( W ) ); - const int halfheight = H / 2; - const int mid = Y + halfheight; + const int halfheight = H / 2; + const int mid = Y + halfheight; - fl_line_style( FL_SOLID, 1 ); + if ( Waveform::fill ) + { + j = start; + for ( int x = X; x <= X + W; ++x, ++j ) + { + Peak p = (*pk)[ j ]; - j = start; - for ( int x = X; x <= X + W; ++x, ++j ) - { - Peak p = (*pk)[ j ]; + p.max *= _scale; + p.min *= _scale; - p.max *= _scale; - p.min *= _scale; + const float diff = fabs( p.max - p.min ); - const float diff = fabs( p.max - p.min ); + if ( Waveform::vary_color ) + fl_color( fl_color_average( FL_WHITE, color, min( 1.0f, diff ) ) ); + else + fl_color( color ); - if ( vary_color ) - fl_color( fl_color_average( FL_WHITE, color, min( 1.0f, diff ) ) ); - else - fl_color( color ); + if ( diff > 1.0f ) + fl_color( FL_RED ); - if ( diff > 1.0f ) - fl_color( FL_RED ); - - const int ty = mid + (halfheight * p.min); - const int by = mid + (halfheight * p.max ); - fl_line( x, ty, x, by ); + const int ty = mid + (halfheight * p.min); + const int by = mid + (halfheight * p.max ); + fl_line( x, ty, x, by ); /* if ( outline ) */ /* { */ @@ -83,48 +89,48 @@ draw_waveform ( int ox, int X, int Y, int W, int H, Audio_File *_clip, int chann /* fl_line( x, by + 2, x, by ); */ /* } */ - } - - fl_line_style( FL_SOLID, 0 ); - - if ( outline ) - { - - fl_color( fl_darker( fl_darker( color ) ) ); - - fl_line_style( FL_SOLID, 2 ); - - fl_begin_line(); - - j = start; - for ( int x = X; x <= X + W; ++x, ++j ) - { - Peak p = (*pk)[ j ]; - - p.min *= _scale; - - fl_vertex( x, Y + (H / 2) + ((float)H / 2 * p.min )); + } } - fl_end_line(); - fl_begin_line(); - - j = start; - for ( int x = X; x <= X + W; ++x, ++j ) + if ( Waveform::outline ) { - Peak p = (*pk)[ j ]; - p.max *= _scale; + fl_color( fl_darker( fl_darker( color ) ) ); + + fl_line_style( FL_SOLID, 2 ); + + fl_begin_line(); + + j = start; + for ( int x = X; x <= X + W; ++x, ++j ) + { + Peak p = (*pk)[ j ]; + + p.min *= _scale; + + fl_vertex( x, Y + (H / 2) + ((float)H / 2 * p.min )); + } + + fl_end_line(); + + fl_begin_line(); + + j = start; + for ( int x = X; x <= X + W; ++x, ++j ) + { + Peak p = (*pk)[ j ]; + + p.max *= _scale; + + fl_vertex( x, Y + (H / 2) + ((float)H / 2 * p.max )); + } + + fl_end_line(); + + fl_line_style( FL_SOLID, 0 ); - fl_vertex( x, Y + (H / 2) + ((float)H / 2 * p.max )); } - fl_end_line(); - - fl_line_style( FL_SOLID, 0 ); - + fl_pop_clip(); } - - fl_pop_clip(); -} diff --git a/Waveform.H b/Waveform.H index 5a44f86..b29bfd3 100644 --- a/Waveform.H +++ b/Waveform.H @@ -26,4 +26,15 @@ #include "Audio_File.H" -void draw_waveform ( int rx, int X, int Y, int W, int H, Audio_File *_clip, int channel, float fpp, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ); + +class Waveform { + +public: + + static bool fill; + static bool outline; + static bool vary_color; + + static void draw ( int rx, int X, int Y, int W, int H, Audio_File *_clip, int channel, float fpp, nframes_t _start, nframes_t _end, float _scale, Fl_Color color ); + +};