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.
This commit is contained in:
Jonathan Moore Liles 2012-02-27 19:43:49 -08:00
parent e9aca6809e
commit e98326103e
4 changed files with 108 additions and 42 deletions

View File

@ -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;

View File

@ -27,6 +27,7 @@
#include <jack/ringbuffer.h>
#include <jack/thread.h>
#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;

View File

@ -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();

View File

@ -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;