From e98326103e04d3627992b804f79808eae7ca7c72 Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Mon, 27 Feb 2012 19:43:49 -0800 Subject: [PATCH] MIDI input on 'control' port triggers patterns in Trigger playback mode. Notes 1-128 on Channel 1 correspond to patterns. NOTE ON triggers the pattern at the given moment, a second NOTE ON stops it at a given moment. NOTE OFF does nothing. Also, patterns triggered via the GUI are no longer forced to be in lock-step. --- src/gui/ui.fl | 22 ++++++++---- src/jack.C | 93 ++++++++++++++++++++++++++++++++++++++++++++++----- src/pattern.C | 34 ++++--------------- src/pattern.H | 1 + 4 files changed, 108 insertions(+), 42 deletions(-) diff --git a/src/gui/ui.fl b/src/gui/ui.fl index 5ef2b1a..2b525ad 100644 --- a/src/gui/ui.fl +++ b/src/gui/ui.fl @@ -1673,14 +1673,24 @@ switch ( m ) { case 1: { - pattern *p = pattern::pattern_by_number( atoi( label() ) ); - + pattern *p = pattern::pattern_by_number( atoi( label() ) ); + if ( p ) - { - if ( p->mode() == MUTE ) - p->mode( PLAY ); + { + if ( TRIGGER == song.play_mode ) + { + if ( p->playing() ) + p->stop(); else - p->mode( MUTE ); + p->trigger(); + } + else + { + if ( p->mode() == PLAY ) + p->mode( MUTE ); + else + p->mode( PLAY ); + } } break; diff --git a/src/jack.C b/src/jack.C index 0ee317e..df230dd 100644 --- a/src/jack.C +++ b/src/jack.C @@ -27,6 +27,7 @@ #include #include +#include "jack.H" #include "non.H" #include "transport.H" #include "pattern.H" @@ -300,22 +301,84 @@ process ( jack_nframes_t nframes, void *arg ) onph = nph; + if ( old_play_mode != song.play_mode ) + { + switch ( old_play_mode ) + { + case PATTERN: + case TRIGGER: + DMESSAGE( "Stopping all patterns" ); + stop_all_patterns(); + break; + } + old_play_mode = song.play_mode; + } + // DMESSAGE( "tpp %f %lu-%lu", transport.ticks_per_period, ph, nph ); - switch ( old_play_mode ) + /* now handle control input */ { - case PATTERN: - case TRIGGER: - stop_all_patterns(); - break; + int j = CONTROL; + + static midievent e; + + input[j].buf = jack_port_get_buffer( input[j].port, nframes ); + + jack_midi_event_t ev; + + jack_nframes_t count = jack_midi_get_event_count( input[j].buf ); + + for ( uint i = 0; i < count; ++i ) + { +// MESSAGE( "Got midi input!" ); + + jack_midi_event_get( &ev, input[j].buf, i ); + + /* time is frame within cycle, convert to absolute tick */ + e.timestamp( ph + (ev.time / transport.frames_per_tick) ); + e.status( ev.buffer[0] ); + e.lsb( ev.buffer[1] ); + if ( ev.size == 3 ) + e.msb( ev.buffer[2] ); + + /* no need to pass it to the GUI, we can trigger patterns here */ + + if ( e.channel() == 0 && e.is_note_on() ) + { + if ( e.note() < pattern::patterns() ) + { + pattern *p = pattern::pattern_by_number( e.note() + 1 ); + + if ( p->playing() ) + { + DMESSAGE( "Untriggering pattern %i", e.note() ); + + if ( e.note() < pattern::patterns() ) + { + pattern *p = pattern::pattern_by_number( e.note() + 1 ); + + DMESSAGE( "Untriggering pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() ); + + p->trigger( ph, e.timestamp() ); + } + } + else + { + DMESSAGE( "Triggering pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() ); + + p->trigger( e.timestamp(), -1 ); + } + } + } + } } + switch ( song.play_mode ) { case SEQUENCE: playlist->play( ph, nph ); break; case PATTERN: - case TRIGGER: { for ( uint i = pattern::patterns(); i--; ) { @@ -325,18 +388,29 @@ process ( jack_nframes_t nframes, void *arg ) p->play( ph, nph ); } + break; + } + case TRIGGER: + { + for ( uint i = pattern::patterns(); i--; ) + { + pattern *p = pattern::pattern_by_number( i + 1 ); + p->play( ph, nph ); + } break; } } - old_play_mode = song.play_mode; - oph = ph; /* handle midi input */ - for ( int j = transport.recording ? 2 : 1; j--; ) +// for ( int j = transport.recording ? 2 : 1; j--; ) + + if ( transport.recording ) { + int j = PERFORMANCE; + static midievent e; input[j].buf = jack_port_get_buffer( input[j].port, nframes ); @@ -363,6 +437,7 @@ process ( jack_nframes_t nframes, void *arg ) } } + schedule: const int subticks_per_period = transport.ticks_per_period * subticks_per_tick; diff --git a/src/pattern.C b/src/pattern.C index 7260ffd..3681adf 100644 --- a/src/pattern.C +++ b/src/pattern.C @@ -45,8 +45,6 @@ pattern::pattern ( void ) _note = 8; int _bars = 2; - _triggered = false; - // we need to reinitalize this. data *d = const_cast< data * >( _rd ); @@ -306,6 +304,12 @@ pattern::trigger ( tick_t start, tick_t end ) _index = 0; } +/* trigger forever */ +void +pattern::trigger ( void ) +{ + trigger( transport.frame / transport.frames_per_tick, -1 ); +} void pattern::stop ( void ) const @@ -321,21 +325,6 @@ pattern::stop ( void ) const void pattern::mode ( int n ) { - if ( song.play_mode == TRIGGER ) - { - switch ( n ) - { - case PLAY: - _triggered = true; - break; - case MUTE: - _triggered = false; - break; - } - - return; - } - if ( n == SOLO ) { if ( pattern::_solo ) @@ -355,15 +344,6 @@ pattern::mode ( int n ) int pattern::mode ( void ) const { - - if ( song.play_mode == TRIGGER ) - { - if ( ! _triggered ) - return MUTE; - else - return PLAY; - } - if ( pattern::_solo ) { if ( pattern::_solo == _number ) @@ -477,7 +457,7 @@ done: if ( _end == end ) { - /* we're doing playing this trigger */ + /* we're done playing this trigger */ DMESSAGE( "Pattern %d ended at tick %lu (ls: %lu, le: %lu, o: %lu)", number(), end, _start, _end, offset ); stop(); diff --git a/src/pattern.H b/src/pattern.H index f3f4041..b7415c8 100644 --- a/src/pattern.H +++ b/src/pattern.H @@ -79,6 +79,7 @@ public: const char * row_name ( int r ) const; void draw_row_names ( Canvas *c ) const; void trigger ( tick_t start, tick_t end ); + void trigger ( void ); void stop ( void ) const; void play ( tick_t start, tick_t end ) const;