]> git.alsa-project.org Git - alsa-tools.git/commitdiff
envy24control midi updates
authorJaroslav Kysela <perex@perex.cz>
Tue, 26 Jul 2005 11:37:11 +0000 (11:37 +0000)
committerJaroslav Kysela <perex@perex.cz>
Tue, 26 Jul 2005 11:37:11 +0000 (11:37 +0000)
I have enhanced the midi control of envy24control.

1) I have fixed midi feedback, where issuing a controller event resulted in
the controller value beeing sent to the midi port again.

2) I have added midi controllers for the "mute" buttons, which can now be
controller via midi.

3) and while rewriting the midi code to support the mute buttons several
off-by-one errors have been fixed.
From: Dirk Jagdmann <doj@cubic.org>

envy24control/midi.c
envy24control/midi.h
envy24control/mixer.c

index 29f9279c1c4d1afab8efa1aa4fb106d377da419f..a6bfaf5d890b1a2ad4c1d823f0d2a3b5bf504ed2 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
    envy24control.c - Env24 chipset (ICE1712) control utility
    midi controller code
-   (c) 2004 by Dirk Jagdmann <doj@cubic.org>
+   (c) 2004, 2005 by Dirk Jagdmann <doj@cubic.org>
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
 static snd_seq_t *seq=0;
 static int client, clientId, port, ch;
 static char *portname=0, *appname=0;
-static int nofeedback=-1;
 static int maxstreams=0;
-static uint8_t currentvalues[128];
+static int currentvalue[128];
 
 void midi_maxstreams(int m)
 {
-  maxstreams=(m-1)*2;
+  maxstreams=m*2;
 }
 
 int midi_close()
@@ -56,6 +55,10 @@ static void do_controller(int c, int v)
 {
   snd_seq_event_t ev;
   if(!seq) return;
+  if(currentvalue[c]==v) return;
+#if 0
+  fprintf(stderr, "do_controller(%i,%i)\n",c,v);
+#endif
   snd_seq_ev_clear(&ev);
   snd_seq_ev_set_source(&ev, port);
   snd_seq_ev_set_subs(&ev);
@@ -63,21 +66,34 @@ static void do_controller(int c, int v)
   snd_seq_ev_set_controller(&ev,ch,c,v);
   snd_seq_event_output(seq, &ev);
   snd_seq_drain_output(seq);
+
+  currentvalue[c]=v;
 }
 
 int midi_controller(int c, int v)
 {
-  if(c==nofeedback) return 0;
   if(c<0 || c>127) return 0;
 
   v*=127; v/=96;
   if(v<0) v=0;
   if(v>127) v=127;
-  currentvalues[c]=v;
+#if 0
+  fprintf(stderr, "midi_controller(%i,%i)\n",c,v);
+#endif
+  if(currentvalue[c]==v-1 || currentvalue[c]==v-2) return 0; /* because of 96to127 conversion values can differ up to two integers */
   do_controller(c,v);
   return 0;
 }
 
+int midi_button(int b, int v)
+{
+  if(b<0) return 0;
+  b+=maxstreams;
+  if(b>127) return 0;
+  do_controller(b, v?127:0);
+  return 0;
+}
+
 int midi_init(char *appname, int channel)
 {
   snd_seq_client_info_t *clientinfo;
@@ -87,6 +103,9 @@ int midi_init(char *appname, int channel)
   if(seq)
     return 0;
 
+  for(npfd=0; npfd!=128; ++npfd)
+    currentvalue[npfd]=-1;
+
   ch=channel;
 
   if(snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0)
@@ -139,6 +158,7 @@ int midi_init(char *appname, int channel)
 }
 
 void mixer_adjust(GtkAdjustment *adj, gpointer data);
+void mixer_set_mute(int stream, int left, int right);
 
 void midi_process(gpointer data, gint source, GdkInputCondition condition)
 {
@@ -158,15 +178,27 @@ void midi_process(gpointer data, gint source, GdkInputCondition condition)
          fprintf(stderr, "Channel %02d: Controller %03d: Value:%d\n",
                  ev->data.control.channel, ev->data.control.param, ev->data.control.value);
 #endif
-         if(ev->data.control.channel == ch && ev->data.control.param < maxstreams)
+         if(ev->data.control.channel == ch)
            {
-             int stream=ev->data.control.param+1;
-             long data=((stream/2)<<16)|(stream&1);
-             int v=ev->data.control.value; v*=96; v/=127;
-             gtk_adjustment_set_value(adj, 96-v);
-             nofeedback=ev->data.control.param;
-             mixer_adjust(adj, (gpointer)data);
-             nofeedback=-1;
+             currentvalue[ev->data.control.param]=ev->data.control.value;
+             if(ev->data.control.param < maxstreams)
+               {
+                 int stream=ev->data.control.param;
+                 long data=((stream/2+1)<<16)|(stream&1);
+                 int v=ev->data.control.value; v*=96; v/=127;
+                 gtk_adjustment_set_value(adj, 96-v);
+                 mixer_adjust(adj, (gpointer)data);
+               }
+             else if(ev->data.control.param < maxstreams*2)
+               {
+                 int b=ev->data.control.param-maxstreams;
+                 int left=-1, right=-1;
+                 if(b&1)
+                   right=ev->data.control.value;
+                 else
+                   left=ev->data.control.value;
+                 mixer_set_mute(b/2+1, left, right);
+               }
            }
          break;
 
@@ -178,8 +210,14 @@ void midi_process(gpointer data, gint source, GdkInputCondition condition)
          if(ev->data.connect.dest.client!=clientId)
            {
              int i;
-             for(i=0; i<sizeof(currentvalues); ++i)
-               do_controller(i, currentvalues[i]);
+             for(i=0; i!=128; ++i)
+               if(currentvalue[i] >= 0)
+                 {
+                   /* set currentvalue[i] to a fake value, so the check in do_controller does not trigger */
+                   int v=currentvalue[i];
+                   currentvalue[i]=-1;
+                   do_controller(i, v);
+                 }
            }
          break;
        }
index e87eff92c4674fd524a0213972507b0c37fb2fd7..5deb7457ad2acb201bcf20cef0a786c405d46915 100644 (file)
@@ -8,5 +8,6 @@ int midi_close();
 void midi_maxstreams(int);
 int midi_controller(int c, int v);
 void midi_process(gpointer data, gint source, GdkInputCondition condition);
+int midi_button(int b, int v);
 
 #endif
index 3870afadeb9a293e2ee4f548120d645c83d36b4c..7951be0ff38fc6c38e97a5dc628d06250ee7d713 100644 (file)
@@ -63,8 +63,8 @@ void mixer_update_stream(int stream, int vol_flag, int sw_flag)
                        toggle_set(mixer_stereo_toggle[stream-1], FALSE);
                gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][0]), 96 - v[0]);
                gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][1]), 96 - v[1]);
-               midi_controller(stream*2-1, v[0]);
-               midi_controller(stream*2,   v[1]);
+               midi_controller((stream-1)*2,   v[0]);
+               midi_controller((stream-1)*2+1, v[1]);
        }
        if (sw_flag) {
                snd_ctl_elem_value_t *sw;
@@ -81,6 +81,8 @@ void mixer_update_stream(int stream, int vol_flag, int sw_flag)
                        toggle_set(mixer_stereo_toggle[stream-1], FALSE);
                toggle_set(mixer_mute_toggle[stream-1][0], !v[0] ? TRUE : FALSE);
                toggle_set(mixer_mute_toggle[stream-1][1], !v[1] ? TRUE : FALSE);
+               midi_button((stream-1)*2, v[0]);
+               midi_button((stream-1)*2+1, v[1]);
        }
 }
 
@@ -98,10 +100,12 @@ static void set_switch1(int stream, int left, int right)
        if (left >= 0 && left != snd_ctl_elem_value_get_boolean(sw, 0)) {
                snd_ctl_elem_value_set_boolean(sw, 0, left);
                changed = 1;
+               midi_button((stream-1)*2, left);
        }
        if (right >= 0 && right != snd_ctl_elem_value_get_boolean(sw, 1)) {
                snd_ctl_elem_value_set_boolean(sw, 1, right);
                changed = 1;
+               midi_button((stream-1)*2+1, right);
        }
        if (changed) {
                err = snd_ctl_elem_write(ctl, sw);
@@ -127,6 +131,15 @@ void mixer_toggled_mute(GtkWidget *togglebutton, gpointer data)
        set_switch1(stream, vol[0], vol[1]);
 }
 
+void mixer_set_mute(int stream, int left, int right)
+{
+       if (left >= 0)
+               toggle_set(mixer_mute_toggle[stream-1][0], left ? TRUE : FALSE);
+       if (right >= 0)
+               toggle_set(mixer_mute_toggle[stream-1][1], right ? TRUE : FALSE);
+       set_switch1(stream, left, right);
+}
+
 static void set_volume1(int stream, int left, int right)
 {
        snd_ctl_elem_value_t *vol;
@@ -142,12 +155,12 @@ static void set_volume1(int stream, int left, int right)
        if (left >= 0) {
                change |= (snd_ctl_elem_value_get_integer(vol, 0) != left);
                snd_ctl_elem_value_set_integer(vol, 0, left);
-               midi_controller(stream*2-1, left);
+               midi_controller((stream-1)*2, left);
        }
        if (right >= 0) {
                change |= (snd_ctl_elem_value_get_integer(vol, 1) != right);
                snd_ctl_elem_value_set_integer(vol, 1, right);
-               midi_controller(stream*2, right);
+               midi_controller((stream-1)*2+1, right);
        }
        if (change) {
                if ((err = snd_ctl_elem_write(ctl, vol)) < 0 && err != -EBUSY)