Browse Source

Implement Queue playback mode.

Pattern muteing/unmuteing (via GUI or MIDI) takes effect the next time the
pattern loops.
tags/non-sequencer-v1.9.4
Jonathan Moore Liles 13 years ago
parent
commit
17e32e0282
7 changed files with 91 additions and 20 deletions
  1. +2
    -1
      src/grid.C
  2. +1
    -1
      src/grid.H
  3. +7
    -2
      src/gui/ui.fl
  4. +26
    -11
      src/jack.C
  5. +2
    -1
      src/non.H
  6. +50
    -0
      src/pattern.C
  7. +3
    -4
      src/pattern.H

+ 2
- 1
src/grid.C View File

@@ -822,7 +822,8 @@ Grid::mode ( int m )
{
_mode = m;

signal_settings_change();
/* can't do this in RT thread, sorry. */
/// signal_settings_change();
}

int


+ 1
- 1
src/grid.H View File

@@ -122,7 +122,7 @@ protected:
volatile mutable tick_t _index; /* playhead, relative to start -- primarily used to draw the playhead */
volatile mutable bool _playing; /* true if currently playing */

volatile int _mode; /* mute, solo */
mutable volatile int _mode; /* mute, solo */

// FIXME: shouldn't this be "volatile"?
// const volatile data *_rd; /* read only data used by RT thread */


+ 7
- 2
src/gui/ui.fl View File

@@ -185,7 +185,7 @@ if ( Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape )
if ( maybe_save_song() )
quit();} open
xywh {209 100 865 800} type Double box PLASTIC_UP_BOX color 37 resizable xclass non size_range {600 420 0 0} visible
xywh {856 305 865 800} type Double box PLASTIC_UP_BOX color 37 resizable xclass non size_range {600 420 0 0} visible
} {
Fl_Menu_Bar menu_bar {open
xywh {0 0 869 30} color 37
@@ -983,7 +983,7 @@ else
} {
MenuItem {} {
label Pattern
callback {song.play_mode = PATTERN;}
callback {song.play_mode = PATTERN;} selected
xywh {5 5 40 25}
}
MenuItem {} {
@@ -996,6 +996,11 @@ else
callback {song.play_mode = TRIGGER;}
xywh {25 25 40 25}
}
MenuItem {} {
label Queue
callback {song.play_mode = QUEUE;}
xywh {0 0 40 24}
}
}
}
Fl_Group {} {open


+ 26
- 11
src/jack.C View File

@@ -307,6 +307,7 @@ process ( jack_nframes_t nframes, void *arg )
{
case PATTERN:
case TRIGGER:
case QUEUE:
DMESSAGE( "Stopping all patterns" );
stop_all_patterns();
break;
@@ -343,41 +344,55 @@ 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.note() < pattern::patterns() )
{
pattern *p = pattern::pattern_by_number( e.note() + 1 );
if ( p->playing() )
if ( TRIGGER == song.play_mode )
{
DMESSAGE( "Untriggering pattern %i", e.note() );
if ( e.note() < pattern::patterns() )
if ( p->playing() )
{
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 );
}
}
else
{
DMESSAGE( "Triggering pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() );
p->trigger( e.timestamp(), -1 );
if ( p->mode() == PLAY )
{
DMESSAGE( "Dequeuing pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() );
p->mode( MUTE );
}
else
{
DMESSAGE( "Queuing pattern %i ph=%lu, ts=%lu", e.note(), ph, e.timestamp() );
p->mode( PLAY );
}
}
}
}
}
}

switch ( song.play_mode )
{
case SEQUENCE:
playlist->play( ph, nph );
break;
case QUEUE:
case PATTERN:
{
for ( uint i = pattern::patterns(); i--; )


+ 2
- 1
src/non.H View File

@@ -51,7 +51,8 @@ bool save_song ( const char *name );
enum play_mode_e {
PATTERN,
SEQUENCE,
TRIGGER
TRIGGER,
QUEUE
// PHRASE,
};



+ 50
- 0
src/pattern.C View File

@@ -43,6 +43,9 @@ pattern::pattern ( void )
_ppqn = 4;
_bpb = 4;
_note = 8;

_queued = -1;

int _bars = 2;

// we need to reinitalize this.
@@ -325,6 +328,12 @@ pattern::stop ( void ) const
void
pattern::mode ( int n )
{
if ( QUEUE == song.play_mode )
{
queue( n );
return;
}

if ( n == SOLO )
{
if ( pattern::_solo )
@@ -355,6 +364,19 @@ pattern::mode ( void ) const
return Grid::mode();
}

/* queue a mode change for the next loop */
void
pattern::queue ( int m )
{
_queued = m;
}

int
pattern::queue ( void ) const
{
return _queued;
}

/* WARNING: runs in the RT thread! */
// output notes from /start/ to /end/ (absolute)
void
@@ -389,11 +411,33 @@ pattern::play ( tick_t start, tick_t end ) const

_index = tick % d->length;

bool reset_queued = false;

if ( _index < end - start )
{
/* period covers the beginning of the loop */
DMESSAGE( "%s pattern %d at tick %lu (ls: %lu, le: %lu, o: %lu)", _playing ? "Looped" : "Triggered", number(), start, _start, _end, offset );

_cleared = false;

if ( PLAY == _queued )
{
/* set the start point to loop boundary */
start = start - _index;
_mode = PLAY;
reset_queued = true;
}
}
else if ( _index >= d->length - ( end - start ) )
{
if ( MUTE == _queued )
{
/* set the end point to loop boundary */
end = end - _index;

reset_queued = true;
}
}

_playing = true;
@@ -455,6 +499,12 @@ try_again:

done:

if ( _queued >= 0 && reset_queued )
{
_mode = _queued;
_queued = -1;
}

if ( _end == end )
{
/* we're done playing this trigger */


+ 3
- 4
src/pattern.H View File

@@ -43,13 +43,12 @@ class pattern : public Grid
bool _recording;
mutable volatile bool _cleared;

volatile bool _triggered;
mutable volatile int _queued;

// int _key;

int _note;


void _add ( void );


@@ -88,8 +87,8 @@ public:
void record( int mode );
void record_stop ( void );

void toggle_trigger ( void );
bool triggered ( void ) const;
void queue ( int mode );
int queue ( void ) const;

void randomize_row ( int y, int feel, float probability );



Loading…
Cancel
Save