mirror of
				https://github.com/alsa-project/alsa-tools.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	envy24control midi updates
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>
This commit is contained in:
		
							parent
							
								
									d8758b8482
								
							
						
					
					
						commit
						632a2ae802
					
				
					 3 changed files with 72 additions and 20 deletions
				
			
		| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*****************************************************************************
 | 
					/*****************************************************************************
 | 
				
			||||||
   envy24control.c - Env24 chipset (ICE1712) control utility
 | 
					   envy24control.c - Env24 chipset (ICE1712) control utility
 | 
				
			||||||
   midi controller code
 | 
					   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
 | 
					   This program is free software; you can redistribute it and/or
 | 
				
			||||||
   modify it under the terms of the GNU General Public License
 | 
					   modify it under the terms of the GNU General Public License
 | 
				
			||||||
| 
						 | 
					@ -27,13 +27,12 @@
 | 
				
			||||||
static snd_seq_t *seq=0;
 | 
					static snd_seq_t *seq=0;
 | 
				
			||||||
static int client, clientId, port, ch;
 | 
					static int client, clientId, port, ch;
 | 
				
			||||||
static char *portname=0, *appname=0;
 | 
					static char *portname=0, *appname=0;
 | 
				
			||||||
static int nofeedback=-1;
 | 
					 | 
				
			||||||
static int maxstreams=0;
 | 
					static int maxstreams=0;
 | 
				
			||||||
static uint8_t currentvalues[128];
 | 
					static int currentvalue[128];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void midi_maxstreams(int m)
 | 
					void midi_maxstreams(int m)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  maxstreams=(m-1)*2;
 | 
					  maxstreams=m*2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int midi_close()
 | 
					int midi_close()
 | 
				
			||||||
| 
						 | 
					@ -56,6 +55,10 @@ static void do_controller(int c, int v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  snd_seq_event_t ev;
 | 
					  snd_seq_event_t ev;
 | 
				
			||||||
  if(!seq) return;
 | 
					  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_clear(&ev);
 | 
				
			||||||
  snd_seq_ev_set_source(&ev, port);
 | 
					  snd_seq_ev_set_source(&ev, port);
 | 
				
			||||||
  snd_seq_ev_set_subs(&ev);
 | 
					  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_ev_set_controller(&ev,ch,c,v);
 | 
				
			||||||
  snd_seq_event_output(seq, &ev);
 | 
					  snd_seq_event_output(seq, &ev);
 | 
				
			||||||
  snd_seq_drain_output(seq);
 | 
					  snd_seq_drain_output(seq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  currentvalue[c]=v;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int midi_controller(int c, int v)
 | 
					int midi_controller(int c, int v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  if(c==nofeedback) return 0;
 | 
					 | 
				
			||||||
  if(c<0 || c>127) return 0;
 | 
					  if(c<0 || c>127) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  v*=127; v/=96;
 | 
					  v*=127; v/=96;
 | 
				
			||||||
  if(v<0) v=0;
 | 
					  if(v<0) v=0;
 | 
				
			||||||
  if(v>127) v=127;
 | 
					  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);
 | 
					  do_controller(c,v);
 | 
				
			||||||
  return 0;
 | 
					  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)
 | 
					int midi_init(char *appname, int channel)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  snd_seq_client_info_t *clientinfo;
 | 
					  snd_seq_client_info_t *clientinfo;
 | 
				
			||||||
| 
						 | 
					@ -87,6 +103,9 @@ int midi_init(char *appname, int channel)
 | 
				
			||||||
  if(seq)
 | 
					  if(seq)
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for(npfd=0; npfd!=128; ++npfd)
 | 
				
			||||||
 | 
					    currentvalue[npfd]=-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ch=channel;
 | 
					  ch=channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if(snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0)
 | 
					  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_adjust(GtkAdjustment *adj, gpointer data);
 | 
				
			||||||
 | 
					void mixer_set_mute(int stream, int left, int right);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void midi_process(gpointer data, gint source, GdkInputCondition condition)
 | 
					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",
 | 
						  fprintf(stderr, "Channel %02d: Controller %03d: Value:%d\n",
 | 
				
			||||||
		  ev->data.control.channel, ev->data.control.param, ev->data.control.value);
 | 
							  ev->data.control.channel, ev->data.control.param, ev->data.control.value);
 | 
				
			||||||
#endif
 | 
					#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;
 | 
						      currentvalue[ev->data.control.param]=ev->data.control.value;
 | 
				
			||||||
	      long data=((stream/2)<<16)|(stream&1);
 | 
						      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;
 | 
							  int v=ev->data.control.value; v*=96; v/=127;
 | 
				
			||||||
		  gtk_adjustment_set_value(adj, 96-v);
 | 
							  gtk_adjustment_set_value(adj, 96-v);
 | 
				
			||||||
	      nofeedback=ev->data.control.param;
 | 
					 | 
				
			||||||
		  mixer_adjust(adj, (gpointer)data);
 | 
							  mixer_adjust(adj, (gpointer)data);
 | 
				
			||||||
	      nofeedback=-1;
 | 
							}
 | 
				
			||||||
 | 
						      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;
 | 
						  break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,8 +210,14 @@ void midi_process(gpointer data, gint source, GdkInputCondition condition)
 | 
				
			||||||
	  if(ev->data.connect.dest.client!=clientId)
 | 
						  if(ev->data.connect.dest.client!=clientId)
 | 
				
			||||||
	    {
 | 
						    {
 | 
				
			||||||
	      int i;
 | 
						      int i;
 | 
				
			||||||
	      for(i=0; i<sizeof(currentvalues); ++i)
 | 
						      for(i=0; i!=128; ++i)
 | 
				
			||||||
		do_controller(i, currentvalues[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;
 | 
						  break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,5 +8,6 @@ int midi_close();
 | 
				
			||||||
void midi_maxstreams(int);
 | 
					void midi_maxstreams(int);
 | 
				
			||||||
int midi_controller(int c, int v);
 | 
					int midi_controller(int c, int v);
 | 
				
			||||||
void midi_process(gpointer data, gint source, GdkInputCondition condition);
 | 
					void midi_process(gpointer data, gint source, GdkInputCondition condition);
 | 
				
			||||||
 | 
					int midi_button(int b, int v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,8 +63,8 @@ void mixer_update_stream(int stream, int vol_flag, int sw_flag)
 | 
				
			||||||
			toggle_set(mixer_stereo_toggle[stream-1], FALSE);
 | 
								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][0]), 96 - v[0]);
 | 
				
			||||||
		gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][1]), 96 - v[1]);
 | 
							gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][1]), 96 - v[1]);
 | 
				
			||||||
		midi_controller(stream*2-1, v[0]);
 | 
							midi_controller((stream-1)*2,   v[0]);
 | 
				
			||||||
		midi_controller(stream*2,   v[1]);
 | 
							midi_controller((stream-1)*2+1, v[1]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (sw_flag) {
 | 
						if (sw_flag) {
 | 
				
			||||||
		snd_ctl_elem_value_t *sw;
 | 
							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_stereo_toggle[stream-1], FALSE);
 | 
				
			||||||
		toggle_set(mixer_mute_toggle[stream-1][0], !v[0] ? TRUE : 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);
 | 
							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)) {
 | 
						if (left >= 0 && left != snd_ctl_elem_value_get_boolean(sw, 0)) {
 | 
				
			||||||
		snd_ctl_elem_value_set_boolean(sw, 0, left);
 | 
							snd_ctl_elem_value_set_boolean(sw, 0, left);
 | 
				
			||||||
		changed = 1;
 | 
							changed = 1;
 | 
				
			||||||
 | 
							midi_button((stream-1)*2, left);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (right >= 0 && right != snd_ctl_elem_value_get_boolean(sw, 1)) {
 | 
						if (right >= 0 && right != snd_ctl_elem_value_get_boolean(sw, 1)) {
 | 
				
			||||||
		snd_ctl_elem_value_set_boolean(sw, 1, right);
 | 
							snd_ctl_elem_value_set_boolean(sw, 1, right);
 | 
				
			||||||
		changed = 1;
 | 
							changed = 1;
 | 
				
			||||||
 | 
							midi_button((stream-1)*2+1, right);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (changed) {
 | 
						if (changed) {
 | 
				
			||||||
		err = snd_ctl_elem_write(ctl, sw);
 | 
							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]);
 | 
						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)
 | 
					static void set_volume1(int stream, int left, int right)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	snd_ctl_elem_value_t *vol;
 | 
						snd_ctl_elem_value_t *vol;
 | 
				
			||||||
| 
						 | 
					@ -142,12 +155,12 @@ static void set_volume1(int stream, int left, int right)
 | 
				
			||||||
	if (left >= 0) {
 | 
						if (left >= 0) {
 | 
				
			||||||
		change |= (snd_ctl_elem_value_get_integer(vol, 0) != left);
 | 
							change |= (snd_ctl_elem_value_get_integer(vol, 0) != left);
 | 
				
			||||||
		snd_ctl_elem_value_set_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) {
 | 
						if (right >= 0) {
 | 
				
			||||||
		change |= (snd_ctl_elem_value_get_integer(vol, 1) != right);
 | 
							change |= (snd_ctl_elem_value_get_integer(vol, 1) != right);
 | 
				
			||||||
		snd_ctl_elem_value_set_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 (change) {
 | 
				
			||||||
		if ((err = snd_ctl_elem_write(ctl, vol)) < 0 && err != -EBUSY)
 | 
							if ((err = snd_ctl_elem_write(ctl, vol)) < 0 && err != -EBUSY)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue