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:
parent
e9aca6809e
commit
e98326103e
|
@ -1677,10 +1677,20 @@ switch ( m )
|
|||
|
||||
if ( p )
|
||||
{
|
||||
if ( p->mode() == MUTE )
|
||||
p->mode( PLAY );
|
||||
if ( TRIGGER == song.play_mode )
|
||||
{
|
||||
if ( p->playing() )
|
||||
p->stop();
|
||||
else
|
||||
p->trigger();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( p->mode() == PLAY )
|
||||
p->mode( MUTE );
|
||||
else
|
||||
p->mode( PLAY );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
87
src/jack.C
87
src/jack.C
|
@ -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;
|
||||
|
||||
// DMESSAGE( "tpp %f %lu-%lu", transport.ticks_per_period, ph, 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 );
|
||||
|
||||
/* now handle control input */
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue