Pattern muteing/unmuteing (via GUI or MIDI) takes effect the next time the pattern loops.tags/non-sequencer-v1.9.4
| @@ -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 | |||
| @@ -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 */ | |||
| @@ -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 | |||
| @@ -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--; ) | |||
| @@ -51,7 +51,8 @@ bool save_song ( const char *name ); | |||
| enum play_mode_e { | |||
| PATTERN, | |||
| SEQUENCE, | |||
| TRIGGER | |||
| TRIGGER, | |||
| QUEUE | |||
| // PHRASE, | |||
| }; | |||
| @@ -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 */ | |||
| @@ -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 ); | |||