Browse Source

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.
tags/non-sequencer-v1.9.4
Jonathan Moore Liles 13 years ago
parent
commit
e98326103e
4 changed files with 108 additions and 42 deletions
  1. +16
    -6
      src/gui/ui.fl
  2. +84
    -9
      src/jack.C
  3. +7
    -27
      src/pattern.C
  4. +1
    -0
      src/pattern.H

+ 16
- 6
src/gui/ui.fl 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;


+ 84
- 9
src/jack.C 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;


+ 7
- 27
src/pattern.C 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();


+ 1
- 0
src/pattern.H 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;



Loading…
Cancel
Save