new features

Asked by alte_frequenze on 2009-03-09

Hi.
I implemented the mute group feature (like group mute key in hw sequencer - i have a yamaha rm1x) in seq24 (0.9.0).
Would you like to taste it? I love!!
by

Question information

Language:
English Edit question
Status:
Answered
For:
Seq24 Edit question
Assignee:
No assignee Edit question
Last query:
2009-05-29
Last reply:
2009-05-29
emuse (goemusic) said : #1

Hi, can you provide a link/patch for this? I'd love to test that
Frank

hi!
Try this!
I hope everything is ok ... the SEQ24 too (istructions!)
remember: groups work with playing screen set only.
so change the screenset and give the command to make it the playing one (i set the HOME key for this)
Everything is configurable as the original sw with the .seq24rc file.
WOOOW!

diff -rupN seq24-0.9.0_original/SEQ24 seq24-0.9.0/SEQ24
--- seq24-0.9.0_original/SEQ24 2008-09-07 12:54:09.000000000 +0200
+++ seq24-0.9.0/SEQ24 2009-03-17 23:52:42.000000000 +0100
@@ -81,6 +81,12 @@ simple interface.
  There are a total of 32 sets, for a total of
  1024 loops.

+ * Moute groups
+
+ You can mute-unmute (according to the group definition) all traks
+ in the playing screen set, that is the only one who have sequences playing
+ (like live sequencer).
+
  * BPM

  The ; and ' keys will increase/decrease tempo as
@@ -118,6 +124,11 @@ simple interface.
  Holding 'Right Ctrl' will queue a on/off toggle for a
  sequence when the loop ends.

+ * keep queue
+
+ Pushing the selected key (see .seq24rc file) you enter in queue mode
+ until you press 'Right Ctrl'.
+
  [3b] Options Window

  This window allows us to select which sequence gets midi
@@ -265,8 +276,22 @@ simple interface.
         After the list of sequences and their midi events, you can
         set seq24 to handle midi events and change the following:

+ # mute in group
+
+ This controls 32 group of mutes in the same mode of [midi-control].
+ A group is a set of sequences that can change the playing state together.
+ Groups work with the 32 sequences in the playing screen set (see after).
+
+
         bpm up and down, screen set up and down.
- replace, snapshot, and queue ( see the end of 3a )
+ replace, snapshot, queue, group mute active, group mute in learning mode
+ and set the actual screen set as playing ( see the end of 3a )
+
+ [mute-group]
+
+ Here there are the definitions of the state of the 32 sequeces
+ of the playing sreen set when a group is selected.
+ group [first 8 sequences state] [second 8] [third 8] [fourth 8]

         * [midi-clock]
@@ -279,8 +304,14 @@ simple interface.

         The keyboard control is a dump of the keys that seq24
         recognises and its corresponding sequence number.
- There are also the modifier keys: replace, snapshot,
- and queue ( see the end of 3a ).
+
+ * [keyboard-group]
+
+ Same as keyboard-control, but to control groups.
+
+ There are also the modifier keys: screen set up, down, play,
+ group on, group off, learn, replace, snapshot,
+ queue and keep queue ( see the end of 3a ).

         To get the correct keys, run seq24 with --show_keys.

diff -rupN seq24-0.9.0_original/src/globals.h seq24-0.9.0/src/globals.h
--- seq24-0.9.0_original/src/globals.h 2008-10-18 12:13:10.000000000 +0200
+++ seq24-0.9.0/src/globals.h 2009-01-30 21:47:29.000000000 +0100
@@ -33,6 +33,7 @@ using namespace std;
 const int c_mainwnd_rows = 4;
 const int c_mainwnd_cols = 8;
 const int c_seqs_in_set = c_mainwnd_rows * c_mainwnd_cols;
+const int c_gmute_tracks = c_seqs_in_set * c_seqs_in_set;
 const int c_max_sets = 32;
 const int c_total_seqs = c_seqs_in_set * c_max_sets;

diff -rupN seq24-0.9.0_original/src/mainwnd.cpp seq24-0.9.0/src/mainwnd.cpp
--- seq24-0.9.0_original/src/mainwnd.cpp 2008-11-27 18:40:01.000000000 +0100
+++ seq24-0.9.0/src/mainwnd.cpp 2009-03-17 23:37:40.000000000 +0100
@@ -674,7 +674,9 @@ mainwnd::on_key_release_event(GdkEventKe
     if ( a_ev->keyval == m_mainperf->m_key_snapshot_1 ||
             a_ev->keyval == m_mainperf->m_key_snapshot_2 )
         m_mainperf->unset_sequence_control_status( c_status_snapshot );
-
+ if ( a_ev->keyval == m_mainperf->m_key_group_learn ){
+ m_mainperf->unset_mode_group_learn();
+ }
     return false;
 }

@@ -723,7 +725,8 @@ mainwnd::on_key_press_event(GdkEventKey*
                 m_mainperf->set_sequence_control_status( c_status_replace );
             }

- if (a_ev->keyval == m_mainperf->m_key_queue )
+ if ((a_ev->keyval == m_mainperf->m_key_queue )
+ || (a_ev->keyval == m_mainperf->m_key_keep_queue ))
             {
                 m_mainperf->set_sequence_control_status( c_status_queue );
             }
@@ -750,6 +753,25 @@ mainwnd::on_key_press_event(GdkEventKey*
                 m_entry_notes->set_text( * m_mainperf->get_screen_set_notepad(m_mainperf->get_screenset() ));
             }

+ if ( a_ev->keyval == m_mainperf->m_key_set_playing_screenset ){
+ m_mainperf->set_playing_screenset();
+ }
+
+ if ( a_ev->keyval == m_mainperf->m_key_group_on ){
+ m_mainperf->set_mode_group_mute();
+ }
+ if ( a_ev->keyval == m_mainperf->m_key_group_off ){
+ m_mainperf->unset_mode_group_mute();
+ }
+
+ if ( a_ev->keyval == m_mainperf->m_key_group_learn ){
+ m_mainperf->set_mode_group_learn();
+ }
+
+ if( m_mainperf->get_key_groups()->count( a_ev->keyval) != 0 ){
+ m_mainperf->select_and_mute_group( (*m_mainperf->get_key_groups())[a_ev->keyval] );
+ }
+
             if ( a_ev->keyval == m_mainperf->m_key_start )
             {
                 if (is_pattern_playing)
diff -rupN seq24-0.9.0_original/src/optionsfile.cpp seq24-0.9.0/src/optionsfile.cpp
--- seq24-0.9.0_original/src/optionsfile.cpp 2008-09-07 14:38:48.000000000 +0200
+++ seq24-0.9.0/src/optionsfile.cpp 2009-03-17 23:02:22.000000000 +0100
@@ -89,6 +89,36 @@ optionsfile::parse( perform *a_perf )
         next_data_line( &file );
     }

+ /* group midi control */
+ line_after( &file, "[mute-group]");
+
+ int gtrack = 0;
+ sscanf( m_line, "%d", &gtrack );
+ next_data_line( &file );
+
+ int mtx[c_seqs_in_set], j=0;
+ for (int i=0; i< c_seqs_in_set; i++) {
+ a_perf->select_group_mute(j);
+ sscanf (m_line, "%d [%d %d %d %d %d %d %d %d] [%d %d %d %d %d %d %d %d] [%d %d %d %d %d %d %d %d] [%d %d %d %d %d %d %d %d]",
+ &j,
+ &mtx[0], &mtx[1], &mtx[2], &mtx[3],
+ &mtx[4], &mtx[5], &mtx[6], &mtx[7],
+
+ &mtx[8], &mtx[9], &mtx[10], &mtx[11],
+ &mtx[12], &mtx[13], &mtx[14], &mtx[15],
+
+ &mtx[16], &mtx[17], &mtx[18], &mtx[19],
+ &mtx[20], &mtx[21], &mtx[22], &mtx[23],
+
+ &mtx[24], &mtx[25], &mtx[26], &mtx[27],
+ &mtx[28], &mtx[29], &mtx[30], &mtx[31]);
+ for (int k=0; k< c_seqs_in_set; k++) {
+ a_perf->set_group_mute_state(k, mtx[k]);
+ }
+ j++;
+ next_data_line( &file );
+ }
+
     line_after( &file, "[midi-clock]" );
     long buses = 0;
     sscanf( m_line, "%ld", &buses );
@@ -119,19 +149,44 @@ optionsfile::parse( perform *a_perf )
         next_data_line( &file );
     }

+ line_after( &file, "[keyboard-group]" );
+ long groups = 0;
+ sscanf( m_line, "%ld", &groups );
+ next_data_line( &file );
+
+ a_perf->key_groups.clear();
+
+
+ for ( int i=0; i<groups; ++i ){
+
+ long key = 0, group = 0;
+ sscanf( m_line, "%ld %ld", &key, &group );
+ a_perf->key_groups[key] = group;
+ next_data_line( &file );
+ }
+
     sscanf( m_line, "%u %u", &a_perf->m_key_bpm_up,
                              &a_perf->m_key_bpm_dn );
     next_data_line( &file );

- sscanf( m_line, "%u %u", &a_perf->m_key_screenset_up,
- &a_perf->m_key_screenset_dn );
+ sscanf( m_line, "%u %u %u", &a_perf->m_key_screenset_up,
+ &a_perf->m_key_screenset_dn,
+ &a_perf->m_key_set_playing_screenset);
+
     next_data_line( &file );

- sscanf( m_line, "%u %u %u %u",
+ sscanf( m_line, "%u %u %u", &a_perf->m_key_group_on,
+ &a_perf->m_key_group_off,
+ &a_perf->m_key_group_learn);
+
+ next_data_line( &file );
+
+ sscanf( m_line, "%u %u %u %u %u",
             &a_perf->m_key_replace,
             &a_perf->m_key_queue,
             &a_perf->m_key_snapshot_1,
- &a_perf->m_key_snapshot_2 );
+ &a_perf->m_key_snapshot_2,
+ &a_perf->m_key_keep_queue);

     line_after( &file, "[jack-transport]" );
     long flag = 0;
@@ -214,7 +269,9 @@ optionsfile::write( perform *a_perf )

         switch( i ){
-
+ /* 32 mute for channel
+ 32 group mute */
+ case c_seqs_in_set : file << "# mute in group\n"; break;
             case c_midi_control_bpm_up : file << "# bpm up\n"; break;
             case c_midi_control_bpm_dn : file << "# bpm down\n"; break;
             case c_midi_control_ss_up : file << "# screen set up\n"; break;
@@ -222,7 +279,10 @@ optionsfile::write( perform *a_perf )
             case c_midi_control_mod_replace : file << "# mod replace\n"; break;
             case c_midi_control_mod_snapshot : file << "# mod snapshot\n"; break;
             case c_midi_control_mod_queue : file << "# mod queue\n"; break;
-
+ case c_midi_control_mod_gmute : file << "# mod gmute\n"; break;
+ case c_midi_control_mod_glearn : file << "# mod glearn\n"; break;
+ case c_midi_control_play_ss : file << "# screen set play\n"; break;
+
             default: break;
         }

@@ -254,8 +314,33 @@ optionsfile::write( perform *a_perf )

         file << string(outs) << "\n";
     }
-
-
+
+ /* group midi control */
+ file << "\n\n\n[mute-group]\n";
+
+ int mtx[c_seqs_in_set];
+ file << c_gmute_tracks << "\n";
+ for (int j=0; j < c_seqs_in_set; j++ ){
+ a_perf->select_group_mute(j);
+ for (int i=0; i < c_seqs_in_set; i++) {
+ mtx[i] = a_perf->get_group_mute_state(i);
+ }
+ sprintf (outs, "%d [%1d %1d %1d %1d %1d %1d %1d %1d] [%1d %1d %1d %1d %1d %1d %1d %1d] [%1d %1d %1d %1d %1d %1d %1d %1d] [%1d %1d %1d %1d %1d %1d %1d %1d]",
+ j,
+ mtx[0], mtx[1], mtx[2], mtx[3],
+ mtx[4], mtx[5], mtx[6], mtx[7],
+
+ mtx[8], mtx[9], mtx[10], mtx[11],
+ mtx[12], mtx[13], mtx[14], mtx[15],
+
+ mtx[16], mtx[17], mtx[18], mtx[19],
+ mtx[20], mtx[21], mtx[22], mtx[23],
+
+ mtx[24], mtx[25], mtx[26], mtx[27],
+ mtx[28], mtx[29], mtx[30], mtx[31]);
+
+ file << string(outs) << "\n";
+ }

     /* bus mute/unmute data */
     int buses = a_perf->get_master_midi_bus( )->get_num_out_buses();
@@ -312,23 +397,45 @@ optionsfile::write( perform *a_perf )
         file << string(outs) << "\n";
     }

+ file << "\n\n\n[keyboard-group]\n";
+ file << "# Key #, group # \n";
+ file << c_seqs_in_set << "\n";
+
+ for( std::map<long,long>::iterator i = a_perf->key_groups.begin();
+ i != a_perf->key_groups.end(); ++i ){
+
+ sprintf( outs, "%ld %ld", i->first, i->second );
+ file << string(outs) << "\n";
+ }
+
+
     file << "# bpm up, down\n"
          << a_perf->m_key_bpm_up
          << " "
          << a_perf->m_key_bpm_dn << "\n";

- file << "# screen set up, down\n"
+ file << "# screen set up, down, play\n"
          << a_perf->m_key_screenset_up
          << " "
          << a_perf->m_key_screenset_dn
+ << " "
+ << a_perf->m_key_set_playing_screenset
          << "\n";

- file << "# replace, queue, snapshot_1, snapshot 2\n"
+ file << "# group on, off, learn\n"
+ << a_perf->m_key_group_on
+ << " "
+ << a_perf->m_key_group_off
+ << " "
+ << a_perf->m_key_group_learn << "\n";
+
+ file << "# replace, queue, snapshot_1, snapshot 2, keep queue\n"
          << a_perf->m_key_replace << " "
          << a_perf->m_key_queue << " "
          << a_perf->m_key_snapshot_1 << " "
- << a_perf->m_key_snapshot_2 << "\n";
-
+ << a_perf->m_key_snapshot_2 << " "
+ << a_perf->m_key_keep_queue << "\n";
+
     file << "\n\n\n[jack-transport]\n\n"

diff -rupN seq24-0.9.0_original/src/perform.cpp seq24-0.9.0/src/perform.cpp
--- seq24-0.9.0_original/src/perform.cpp 2008-09-07 12:54:09.000000000 +0200
+++ seq24-0.9.0/src/perform.cpp 2009-03-17 23:00:02.000000000 +0100
@@ -38,7 +38,8 @@ perform::perform()

     }
-
+ m_mute_group_selected = 0;
+ m_mode_group = true;
     m_running = false;
     m_looping = false;
     m_inputing = true;
@@ -93,7 +94,39 @@ perform::perform()
     key_events[ GDK_k ] = 30;
     key_events[ GDK_comma ] = 31;

-
+ key_groups[ 33 ] = 0;
+ key_groups[ 34 ] = 1;
+ key_groups[ 163 ] = 2;
+ key_groups[ 36 ] = 3;
+ key_groups[ 37 ] = 4;
+ key_groups[ 38 ] = 5;
+ key_groups[ 47 ] = 6;
+ key_groups[ 40 ] = 7;
+ key_groups[ 81 ] = 8;
+ key_groups[ 87 ] = 9;
+ key_groups[ 69 ] = 10;
+ key_groups[ 82 ] = 11;
+ key_groups[ 84 ] = 12;
+ key_groups[ 89 ] = 13;
+ key_groups[ 85 ] = 14;
+ key_groups[ 73 ] = 15;
+ key_groups[ 65 ] = 16;
+ key_groups[ 83 ] = 17;
+ key_groups[ 68 ] = 18;
+ key_groups[ 70 ] = 19;
+ key_groups[ 71 ] = 20;
+ key_groups[ 72 ] = 21;
+ key_groups[ 74 ] = 22;
+ key_groups[ 75 ] = 23;
+ key_groups[ 90 ] = 24;
+ key_groups[ 88 ] = 25;
+ key_groups[ 67 ] = 26;
+ key_groups[ 86 ] = 27;
+ key_groups[ 66 ] = 28;
+ key_groups[ 78 ] = 29;
+ key_groups[ 77 ] = 30;
+ key_groups[ 59 ] = 31;
+
     m_key_bpm_up = GDK_apostrophe;
     m_key_bpm_dn = GDK_semicolon;

@@ -101,10 +134,16 @@ perform::perform()
     m_key_queue = GDK_Control_R;
     m_key_snapshot_1 = GDK_Alt_L;
     m_key_snapshot_2 = GDK_Alt_R;
+ m_key_keep_queue = 92;

     m_key_screenset_up = GDK_bracketright;
     m_key_screenset_dn = GDK_bracketleft;
+ m_key_set_playing_screenset = 65360;

+ m_key_group_on = 236;
+ m_key_group_off = 39;
+ m_key_group_learn = 65379;
+
     m_key_start = GDK_space;
     m_key_stop = GDK_Escape;

@@ -244,6 +283,119 @@ perform::clear_all( void )

 }

+void
+perform::set_mode_group_mute ()
+{
+ m_mode_group = true;
+ return;
+}
+
+void
+perform::unset_mode_group_mute ()
+{
+ m_mode_group = false;
+ return;
+}
+
+void
+perform::set_group_mute_state (int a_g_track, bool a_mute_state)
+{
+ if (a_g_track < 0)
+ a_g_track = 0;
+ if (a_g_track > c_seqs_in_set)
+ a_g_track = c_seqs_in_set -1;
+ m_mute_group[a_g_track + m_mute_group_selected * c_seqs_in_set] = a_mute_state;
+ return;
+}
+
+bool
+perform::get_group_mute_state (int a_g_track)
+{
+ if (a_g_track < 0)
+ a_g_track = 0;
+ if (a_g_track > c_seqs_in_set)
+ a_g_track = c_seqs_in_set -1;
+ return m_mute_group[a_g_track + m_mute_group_selected * c_seqs_in_set];
+}
+
+void
+perform::select_group_mute (int a_g_mute)
+{
+ int j = (a_g_mute * c_seqs_in_set);
+ int k = m_playing_screen * c_seqs_in_set;
+ if (a_g_mute < 0)
+ a_g_mute = 0;
+ if (a_g_mute > c_seqs_in_set)
+ a_g_mute = c_seqs_in_set -1;
+ if (m_mode_group_learn)
+ for (int i = 0; i < c_seqs_in_set; i++) {
+ if (is_active(i + k)) {
+ assert(m_seqs[i + k]);
+ m_mute_group[i + j] = m_seqs[i + k]->get_playing();
+ }
+ }
+ m_mute_group_selected = a_g_mute;
+ return;
+}
+void perform::set_mode_group_learn (void)
+{
+ set_mode_group_mute();
+ m_mode_group_learn = true;
+ return;
+}
+
+void perform::unset_mode_group_learn (void)
+{
+ m_mode_group_learn = false;
+ return;
+}
+
+void
+perform::select_mute_group ( int a_group )
+{
+ int j = (a_group * c_seqs_in_set);
+ int k = m_playing_screen * c_seqs_in_set;
+ if (a_group < 0)
+ a_group = 0;
+ if (a_group > c_seqs_in_set)
+ a_group = c_seqs_in_set -1;
+ m_mute_group_selected = a_group;
+ for (int i = 0; i < c_seqs_in_set; i++) {
+ if ((m_mode_group_learn) && (is_active(i + k))) {
+ assert(m_seqs[i + k]);
+ m_mute_group[i + j] = m_seqs[i + k]->get_playing();
+ }
+ m_tracks_mute_state[i] = m_mute_group[i + m_mute_group_selected * c_seqs_in_set];
+ }
+ return;
+}
+
+void
+perform::mute_group_tracks (void)
+{
+ if (m_mode_group) {
+ for (int i=0; i< c_seqs_in_set; i++) {
+ for (int j=0; j < c_seqs_in_set; j++) {
+ if ( is_active(i * c_seqs_in_set + j) ) {
+ if ((i == m_playing_screen) && (m_tracks_mute_state[j])) {
+ sequence_playing_on (i * c_seqs_in_set + j);
+ } else {
+ sequence_playing_off (i * c_seqs_in_set + j);
+ }
+ }
+ }
+
+ }
+ }
+}
+
+void
+perform::select_and_mute_group (int a_g_group)
+{
+ select_mute_group(a_g_group);
+ mute_group_tracks();
+ return;
+}

 void
@@ -258,8 +410,6 @@ perform::mute_all_tracks( void )
 }

-
-
 perform::~perform()
 {
     m_inputing = false;
@@ -609,7 +759,6 @@ perform::get_screen_set_notepad( int a_s
      return &m_screen_set_notepad[a_screen_set];
 }

-
 void
 perform::set_screenset( int a_ss )
 {
@@ -628,6 +777,27 @@ perform::get_screenset( void )
     return m_screen_set;
 }

+void
+perform::set_playing_screenset (void)
+{
+ for (int j, i = 0; i < c_seqs_in_set; i++) {
+ j = i + m_playing_screen * c_seqs_in_set;
+ if ( is_active(j) ){
+ assert( m_seqs[j] );
+ m_tracks_mute_state[i] = m_seqs[j]->get_playing();
+ }
+ }
+ m_playing_screen = m_screen_set;
+ mute_group_tracks();
+}
+
+int
+perform::get_playing_screenset (void)
+{
+ return m_playing_screen;
+}
+
+
 void
 perform::set_offset( int a_offset )
 {
@@ -1631,7 +1801,6 @@ perform::handle_midi_control( int a_cont
         case c_midi_control_mod_queue:

             //printf ( "queue\n" );
-

             if ( a_state )
                 set_sequence_control_status( c_status_queue );
@@ -1639,7 +1808,40 @@ perform::handle_midi_control( int a_cont
                 unset_sequence_control_status( c_status_queue );
             break;

+ //andy cases
+ case c_midi_control_mod_gmute:
+
+ printf ( "gmute\n" );
+
+ if (a_state)
+ set_mode_group_mute();
+ else
+ unset_mode_group_mute();
+ break;
+
+ case c_midi_control_mod_glearn:
+
+ //printf ( "glearn\n" );
+
+ if (a_state)
+ set_mode_group_learn();
+ else
+ unset_mode_group_learn();
+ break;
+
+ case c_midi_control_play_ss:
+
+ //printf ( "play_ss\n" );
+
+ set_playing_screenset();
+ break;
+
         default:
+ if ((a_control >= c_seqs_in_set) && (a_control < c_midi_track_ctrl)) {
+ //printf ( "group mute\n" );
+
+ select_and_mute_group(a_control - c_seqs_in_set);
+ }
             break;

     }
@@ -1844,8 +2046,21 @@ void
 perform::sequence_playing_on( int a_sequence )
 {
     if ( is_active(a_sequence) == true ){
+ if (m_mode_group && (m_playing_screen == m_screen_set)
+ && (a_sequence >= (m_playing_screen * c_seqs_in_set))
+ && (a_sequence < ((m_playing_screen + 1) * c_seqs_in_set)))
+ m_tracks_mute_state[a_sequence - m_playing_screen * c_seqs_in_set] = true;
   assert( m_seqs[a_sequence] );
- m_seqs[a_sequence]->set_playing(true);
+ if (!(m_seqs[a_sequence]->get_playing())) {
+ if (m_control_status & c_status_queue ) {
+ if (!(m_seqs[a_sequence]->get_queued()))
+ m_seqs[a_sequence]->toggle_queued();
+ } else
+ m_seqs[a_sequence]->set_playing(true);
+ } else {
+ if ((m_seqs[a_sequence]->get_queued()) && (m_control_status & c_status_queue ))
+ m_seqs[a_sequence]->toggle_queued();
+ }
     }
 }

@@ -1854,8 +2069,21 @@ void
 perform::sequence_playing_off( int a_sequence )
 {
     if ( is_active(a_sequence) == true ){
- assert( m_seqs[a_sequence] );
- m_seqs[a_sequence]->set_playing(false);
+ if (m_mode_group && (m_playing_screen == m_screen_set)
+ && (a_sequence >= (m_playing_screen * c_seqs_in_set))
+ && (a_sequence < ((m_playing_screen + 1) * c_seqs_in_set)))
+ m_tracks_mute_state[a_sequence - m_playing_screen * c_seqs_in_set] = false;
+ assert( m_seqs[a_sequence] );
+ if (m_seqs[a_sequence]->get_playing()) {
+ if (m_control_status & c_status_queue ) {
+ if (!(m_seqs[a_sequence]->get_queued()))
+ m_seqs[a_sequence]->toggle_queued();
+ } else
+ m_seqs[a_sequence]->set_playing(false);
+ } else {
+ if ((m_seqs[a_sequence]->get_queued()) && (m_control_status & c_status_queue ))
+ m_seqs[a_sequence]->toggle_queued();
+ }
     }
 }

diff -rupN seq24-0.9.0_original/src/perform.h seq24-0.9.0/src/perform.h
--- seq24-0.9.0_original/src/perform.h 2008-09-07 14:32:48.000000000 +0200
+++ seq24-0.9.0/src/perform.h 2009-03-17 22:40:10.000000000 +0100
@@ -56,20 +56,34 @@ class midi_control
 const int c_status_replace = 0x01;
 const int c_status_snapshot = 0x02;
 const int c_status_queue = 0x04;
-
-const int c_midi_control_bpm_up = c_seqs_in_set ;
-const int c_midi_control_bpm_dn = c_seqs_in_set + 1;
-const int c_midi_control_ss_up = c_seqs_in_set + 2;
-const int c_midi_control_ss_dn = c_seqs_in_set + 3;
-const int c_midi_control_mod_replace = c_seqs_in_set + 4;
-const int c_midi_control_mod_snapshot = c_seqs_in_set + 5;
-const int c_midi_control_mod_queue = c_seqs_in_set + 6;
-const int c_midi_controls = c_seqs_in_set + 7;
+const int c_midi_track_ctrl = c_seqs_in_set * 2;
+const int c_midi_control_bpm_up = c_midi_track_ctrl ;
+const int c_midi_control_bpm_dn = c_midi_track_ctrl + 1;
+const int c_midi_control_ss_up = c_midi_track_ctrl + 2;
+const int c_midi_control_ss_dn = c_midi_track_ctrl + 3;
+const int c_midi_control_mod_replace = c_midi_track_ctrl + 4;
+const int c_midi_control_mod_snapshot = c_midi_track_ctrl + 5;
+const int c_midi_control_mod_queue = c_midi_track_ctrl + 6;
+//andy midi_control_mod_mute_group
+const int c_midi_control_mod_gmute = c_midi_track_ctrl + 7;
+//andy learn_mute_toggle_mode
+const int c_midi_control_mod_glearn = c_midi_track_ctrl + 8;
+//andy play only this screen set
+const int c_midi_control_play_ss = c_midi_track_ctrl + 9;
+const int c_midi_controls = c_midi_track_ctrl + 10;//7

 class perform
 {
  private:
-
+ //andy mute group
+ bool m_mute_group[c_gmute_tracks];
+ bool m_tracks_mute_state[c_seqs_in_set];
+ bool m_mode_group;
+ bool m_mode_group_learn;
+ int m_mute_group_selected;
+ //andy playing screen
+ int m_playing_screen;
+
     /* vector of sequences */
     sequence *m_seqs[c_max_sequence];

@@ -125,6 +139,8 @@ class perform

     std::map<long,long> key_events;

+ std::map<long,long> key_groups;
+
 #ifdef JACK_SUPPORT

     jack_client_t *m_jack_client;
@@ -150,12 +166,18 @@ class perform

     unsigned int m_key_replace;
     unsigned int m_key_queue;
+ unsigned int m_key_keep_queue;
     unsigned int m_key_snapshot_1;
     unsigned int m_key_snapshot_2;

     unsigned int m_key_screenset_up;
     unsigned int m_key_screenset_dn;
-
+ unsigned int m_key_set_playing_screenset;
+
+ unsigned int m_key_group_on;
+ unsigned int m_key_group_off;
+ unsigned int m_key_group_learn;
+
     unsigned int m_key_start;
     unsigned int m_key_stop;

@@ -209,7 +231,16 @@ class perform

     void set_screenset( int a_ss );
     int get_screenset( void );
-
+ void set_playing_screenset( void );
+ int get_playing_screenset( void );
+ void mute_group_tracks (void);
+ void select_and_mute_group (int a_g_group);
+ void set_mode_group_mute ();
+ void select_group_mute (int a_g_mute);
+ void set_mode_group_learn (void);
+ void unset_mode_group_learn (void);
+ void select_mute_group ( int a_group );
+ void unset_mode_group_mute ();
     void start( bool a_state );
     void stop();

@@ -249,6 +280,8 @@ class perform
     void sequence_playing_on( int a_sequence );
     void sequence_playing_off( int a_sequence );

+ void set_group_mute_state (int a_g_track, bool a_mute_state);
+ bool get_group_mute_state (int a_g_track);
     void mute_all_tracks( void );

     mastermidibus* get_master_midi_bus( );
@@ -266,6 +299,7 @@ class perform

     std::map<long,long> *get_key_events( void ){ return &key_events; };

+ std::map<long,long> *get_key_groups( void ){ return &key_groups; };

     friend class midifile;
     friend class optionsfile;
diff -rupN seq24-0.9.0_original/src/sequence.cpp seq24-0.9.0/src/sequence.cpp
--- seq24-0.9.0_original/src/sequence.cpp 2008-09-07 13:17:27.000000000 +0200
+++ seq24-0.9.0/src/sequence.cpp 2009-01-27 23:37:15.000000000 +0100
@@ -1612,12 +1612,12 @@ sequence::stream_event( event *a_ev )
     link_new();

     if ( m_quanized_rec ){
- if (a_ev->is_note_off()) {
- select_note_events( a_ev->get_timestamp(), a_ev->get_note(),
- a_ev->get_timestamp(), a_ev->get_note(), e_select);
+ if (a_ev->is_note_off()) {
+ select_note_events( a_ev->get_timestamp(), a_ev->get_note(),
+ a_ev->get_timestamp(), a_ev->get_note(), e_select);
             quanize_events( EVENT_NOTE_ON, 0, m_snap_tick, 1 , true );
-
- }
+
+ }
     }
     /* update view */

diff -rupN seq24-0.9.0_original/src/userfile.cpp seq24-0.9.0/src/userfile.cpp
--- seq24-0.9.0_original/src/userfile.cpp 2008-09-07 12:54:09.000000000 +0200
+++ seq24-0.9.0/src/userfile.cpp 2009-03-17 22:35:02.000000000 +0100
@@ -175,19 +175,38 @@ userfile::parse( perform *a_perf )
         next_data_line( &file );
     }

+ line_after( &file, "[keyboard-group]" );
+ long keys = 0;
+ sscanf( m_line, "%ld", &keys );
+ next_data_line( &file );
+
+ a_perf->key_groups.clear();
+
+
+ for ( int i=0; i<keys; ++i ){
+
+ long key = 0, group = 0;
+ sscanf( m_line, "%ld %ld", &key, &group );
+ a_perf->key_groups[key] = group;
+ next_data_line( &file );
+ }
+
+
     sscanf( m_line, "%ld %ld", &a_perf->m_key_bpm_up,
                              &a_perf->m_key_bpm_dn );
     next_data_line( &file );

- sscanf( m_line, "%ld %ld", &a_perf->m_key_screenset_up,
- &a_perf->m_key_screenset_dn );
+ sscanf( m_line, "%ld %ld %ld", &a_perf->m_key_screenset_up,
+ &a_perf->m_key_screenset_dn,
+ &a_perf->m_key_set_playing_screenset);
     next_data_line( &file );

     sscanf( m_line, "%ld %ld %ld %ld",
             &a_perf->m_key_replace,
             &a_perf->m_key_queue,
             &a_perf->m_key_snapshot_1,
- &a_perf->m_key_snapshot_2 );
+ &a_perf->m_key_snapshot_2,
+ &a_perf->m_key_keep_queue);

     line_after( &file, "[jack-transport]" );
     long flag = 0;

emuse (goemusic) said : #3

Hi
is this a windows patch? I'm using linux and I'm not able to apply it. Might also be the copy/past into a text editor that causes line end problems?
If I'm wrong, which patch options should I use?
Thanks
Frank

emuse (goemusic) said : #4

I have reproduced your patch manually (yes !). and compiled successfully on linux. Need to understand now how it works ;)
Let me know if you need this patch version for your purposes as a file or if you want to post it at the seq24 sourceforge mailing list or if you want me to post it. I think there are many of us interested in having those features.
To the seq24 developers: can I deposit this patch somewhere here as a file (I still think there were also copy/paste issues that made the original patch fail in my case, so a file would be best).
Thanks already for all your efforts alte_frequenze.
Frank

Thanx for the interest.
I would be pleased if you contribute in making comprehensible the documentation (SEQ24 file) for changes.
Maybe others can appreciate.

Andy

emuse (goemusic) said : #6

Hi Andy,
here are some suggestions for the documentation. Patch is against 0.9.0original SEQ24 file.
I found that two points needed to be said somewhere, at least I was puzzled for a
while ;) :
1) Group Learn is a modifier key to be pressed TOGETHER with the toggle key and
2) The Group on/off keys are there to enable/disable the whole feature, NOT to toggle group states...

Everything works great here, I just noted some strange behavior when using the queue function together with groups, still have to find out what exactly happens....

It's really nice to have, I actually was waiting for this since a while ago (look into the blueprints 'sequence selection patterns....' ;) )

Cheers
Frank

--- seq24-0.9.0/SEQ24 2008-09-07 12:54:08.000000000 +0200
+++ seq24-0.9.0+letz+af/SEQ24 2009-03-20 19:40:34.000000000 +0100
@@ -80,7 +80,7 @@ simple interface.
  the spin widget labeled set.
  There are a total of 32 sets, for a total of
  1024 loops.
-
+
  * BPM

  The ; and ' keys will increase/decrease tempo as
@@ -98,7 +98,20 @@ simple interface.
  [a ][s ][d ][f ][g ][h ][j ][k ]
  [z ][x ][c ][v ][b ][n ][m ][, ]

- * Replace
+ * Mute/Unmute patterns (Groups)
+
+ You can toggle the playing status of up to 32 previously
+ defined mute/unmute patterns (groups) in the active screen
+ set, similar to hardware sequencers.
+ This is done either by one of the 'group toggle' keys
+ or by a MIDI controller, both assigned in the .seq24rc file .
+ A Mute/Unmute pattern (group) is stored by holding a
+ 'group learn' key while pressing the corresponding
+ 'group toggle' key.
+ There are also keys assigned to turn on/off the group
+ functionality.
+
+ * Replace

  Holding down 'Left Ctrl' while selecting a sequence
  will mute all other sequences and turn on the selected
@@ -116,7 +129,15 @@ simple interface.
         * Queue

  Holding 'Right Ctrl' will queue a on/off toggle for a
- sequence when the loop ends.
+ sequence when the loop ends. Queue also works for mute/unmute
+ patterns (groups), in this case every sequence will toggle
+ its status after its individual loop end.
+
+ * keep queue
+
+ Pressing the 'keep queue' key assigned in the .seq24rc file
+ activates permanent queue mode until you use the temporary
+ Queue function again pressing 'Right Ctrl'.

  [3b] Options Window

@@ -261,13 +282,25 @@ simple interface.
         5 [0 0 0 0 0 0] [1 1 176 1 80 95] [0 0 0 0 0 0]
         6 [0 0 0 0 0 0] [1 1 176 1 96 111] [0 0 0 0 0 0]
         7 [0 0 0 0 0 0] [1 1 176 1 112 127] [0 0 0 0 0 0]
+ # mute in group
+
+ This section controls 32 groups of mutes in the same way as
+ defined for [midi-control]. A group is set of sequences
+ that can toggle their playing state together.
+ Every group contains all 32 sequences in the active screen
+ set (see after).
+
+
+
+ [mute-group]
+
+ Here there are the definitions of the state of the 32 sequences
+ in the playing screen set when a group is selected.
+ group [state of the first 8 sequences] [second 8] [third 8] [fourth 8]

         After the list of sequences and their midi events, you can
         set seq24 to handle midi events and change the following:

- bpm up and down, screen set up and down.
- replace, snapshot, and queue ( see the end of 3a )
-

         * [midi-clock]

@@ -278,13 +311,34 @@ simple interface.
         * [keyboard-control]

         The keyboard control is a dump of the keys that seq24
- recognises and its corresponding sequence number.
- There are also the modifier keys: replace, snapshot,
- and queue ( see the end of 3a ).
-
- To get the correct keys, run seq24 with --show_keys.
-
-
+ recognises and its corresponding sequence number.
+ Note that the first number corresponds to the number of sequences in
+ the active screen set.
+
+ * [keyboard-group]
+
+ Same as keyboard-control, but to control groups.
+
+ #bpm up and down
+ -> keys to control bpm
+ #screen set up and down
+ -> keys for changing the active screenset
+ #group functionality on, group functionality off, group learn
+ -> note that the group learn key is a modifier key to be held while
+ pressing a group toggle key
+ #replace, queue, snapshot_1, snapshot_2, keep queue
+ -> These are the other modifier keys explained in section 3a.
+
+
+ *NOTES*:
+ To see the required key codes when pressed, run seq24 with --show_keys.
+
+ Seq24 will overwrite the .seq24rc file on quit. You should therefore
+ quit seq24 before doing modifications to the .seq24rc file.
+
+ Some keys should not be assigned to control sequences in seq24 as they
+ are already assigned in the seq24 menu (with ctrl).
+

    [3f] JACK Transport

Guido Scholz (gscholz) said : #7

Hi alte_frequenze,
your mute group feature was accepted for the seq24 repository. Can you please send me your real name and E-Mail address to honour your contribution in the changelog file?
Regards
Guido

_________________________________________________________________
PiĆ¹ di 30 stazioni. Ascolta la Radio su Messenger!
http://messenger.it/radioMessenger.aspx

_________________________________________________________________
Messenger 2009: scaricalo gratis!
http://messenger.it/

Hi Guido!

Andrea delle Canne
<email address hidden>

I'm happy!

Did someone have a look to new parts of documentation? (changed or good has is?)

By.

Guido Scholz (gscholz) said : #11

Hi Andrea,
thanks for your reply. The documentation is still missing. Can you attach a patch here or even better join the user mailing list at sourceforge [1] and send it to the list?
Guido

[1]: http://sourceforge.net/mail/?group_id=103685

Can you help with this problem?

Provide an answer of your own, or ask alte_frequenze for more information if necessary.

To post a message you must log in.