From 71e058369651b48dd0e45681109eea885aaca044 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Wed, 29 Feb 2012 19:01:18 -0800 Subject: [PATCH] Improve queue playback mode. Flash pattern trigger with color of queued state. Also, use Channel 0 CC 20 0-127 for pattern triggering instead of NOTE ONs. --- src/gui/ui.fl | 44 +++++++++++++++++++++++++------------------- src/jack.C | 24 ++++++++++++++++-------- src/pattern.C | 19 ++++++++++++++++--- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/gui/ui.fl b/src/gui/ui.fl index 667d504..2642474 100644 --- a/src/gui/ui.fl +++ b/src/gui/ui.fl @@ -1750,7 +1750,9 @@ widget_class Triggers {open } {} Function {populate( void )} {open private return_type void } { - code {int bw = (w() / 16); + code {_timer = 0; + +int bw = (w() / 16); int bh = h() / (128/ 16); begin(); @@ -1799,13 +1801,21 @@ redraw();} {} } Function {update( void )} {open return_type void } { - code {if ( ! takesevents() ) + code {++_timer; + +if ( ! takesevents() ) return; int i; for ( i = 0; i < MAX_PATTERN; i++ ) { + Fl_Color mode_color[3]; + + mode_color[PLAY] = FL_GREEN; + mode_color[MUTE] = FL_GRAY; + mode_color[SOLO] = FL_RED; + Trigger *b = (Trigger*)(((Fl_Pack*)rows->child( i / 16 ))->child( i % 16 )); if ( i >= pattern::patterns() ) @@ -1821,22 +1831,15 @@ for ( i = 0; i < MAX_PATTERN; i++ ) { b->color( fl_lighter( FL_GRAY ) ); - Fl_Color c = FL_BLUE; - - switch ( p->mode() ) - { - case MUTE: - c = FL_GRAY; - break; - case SOLO: - c = FL_RED; - break; - case PLAY: - c = FL_GREEN; - break; - } - - b->selection_color( c ); + b->selection_color( mode_color[ p->mode() ] ); + + if ( p->queue() >= 0 ) + { + if ( _timer % 16 < 8 ) + { + b->color( mode_color[ p->queue() ] ); + } + } b->value( (double)p->index() / p->length() ); } @@ -1845,7 +1848,8 @@ for ( i = 0; i < MAX_PATTERN; i++ ) b->value( 0 ); } -}} {} +}} {selected + } } Function {resize( int X, int Y, int W, int H )} {open return_type void } { @@ -1866,4 +1870,6 @@ for ( i = 0; i < MAX_PATTERN; i++ ) Fl_Group::resize( X, Y, W, H );} {} } + decl {unsigned long _timer;} {private local + } } diff --git a/src/jack.C b/src/jack.C index eed2a7c..195580a 100644 --- a/src/jack.C +++ b/src/jack.C @@ -43,6 +43,13 @@ #define jack_midi_event_write( b, f, d, s ) jack_midi_event_write( b, f, d, s, nframes ) #endif + +/* MIDI channel to listen for pattern control changes on */ +int pattern_control_channel = 0; + +/* which control change number to use for pattern control */ +int pattern_control_cc = 20; + jack_client_t *client; int sample_rate; @@ -345,25 +352,26 @@ process ( jack_nframes_t nframes, void *arg ) /* no need to pass it to the GUI, we can trigger patterns here */ - - if ( e.channel() == 0 && e.is_note_on() ) + if ( e.channel() == pattern_control_channel && + e.opcode() == midievent::CONTROL_CHANGE && + e.lsb() == pattern_control_cc ) { - if ( e.note() < pattern::patterns() ) + if ( e.msb() < pattern::patterns() ) { - pattern *p = pattern::pattern_by_number( e.note() + 1 ); + pattern *p = pattern::pattern_by_number( e.msb() + 1 ); if ( TRIGGER == song.play_mode ) { if ( p->playing() ) { - DMESSAGE( "Untriggering pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() ); + DMESSAGE( "Untriggering pattern %i ph=%lu, ts=%lu", e.msb(), ph, e.timestamp() ); p->trigger( ph, e.timestamp() ); } else { - DMESSAGE( "Triggering pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() ); + DMESSAGE( "Triggering pattern %i ph=%lu, ts=%lu", e.msb(), ph, e.timestamp() ); p->trigger( e.timestamp(), -1 ); } @@ -372,12 +380,12 @@ process ( jack_nframes_t nframes, void *arg ) { if ( p->mode() == PLAY ) { - DMESSAGE( "Dequeuing pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() ); + DMESSAGE( "Dequeuing pattern %i ph=%lu, ts=%lu", e.msb(), ph, e.timestamp() ); p->mode( MUTE ); } else { - DMESSAGE( "Queuing pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() ); + DMESSAGE( "Queuing pattern %i ph=%lu, ts=%lu", e.msb(), ph, e.timestamp() ); p->mode( PLAY ); } diff --git a/src/pattern.C b/src/pattern.C index 7dab22e..ad68abb 100644 --- a/src/pattern.C +++ b/src/pattern.C @@ -420,12 +420,25 @@ pattern::play ( tick_t start, tick_t end ) const _cleared = false; - if ( PLAY == _queued ) + if ( PLAY == _queued || SOLO == _queued ) { /* set the start point to loop boundary */ start = start - _index; - _mode = PLAY; - + _mode = _queued; + + if ( SOLO == _mode ) + { + if ( pattern::_solo ) + ((Grid*)pattern::pattern_by_number( pattern::_solo ))->mode( PLAY ); + + pattern::_solo = _number; + } + else + { + if ( pattern::_solo == _number ) + pattern::_solo = 0; + } + reset_queued = true; } }