/*****************************************************************************
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()
{
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);
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;
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)
}
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)
{
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;
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;
}
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;
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]);
}
}
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);
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;
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)