| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | /*****************************************************************************
 | 
					
						
							|  |  |  |    patchbay.c - patchbay/router code | 
					
						
							|  |  |  |    Copyright (C) 2000 by Jaroslav Kysela <perex@suse.cz> | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |    This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |    modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |    as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |    of the License, or (at your option) any later version. | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |    This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU General Public License for more details. | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with this program; if not, write to the Free Software | 
					
						
							|  |  |  |    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | 
					
						
							|  |  |  | ******************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "envy24control.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | #define SPDIF_PLAYBACK_ROUTE_NAME	"IEC958 Playback Route"
 | 
					
						
							|  |  |  | #define ANALOG_PLAYBACK_ROUTE_NAME	"H/W Playback Route"
 | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define toggle_set(widget, state) \
 | 
					
						
							|  |  |  | 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), state); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-24 19:05:44 +00:00
										 |  |  | static int stream_active[MAX_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS]; | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | extern int output_channels, input_channels, pcm_output_channels, spdif_channels; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | static int is_active(GtkWidget *widget) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return GTK_TOGGLE_BUTTON(widget)->active ? 1 : 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int get_toggle_index(int stream) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	int err, out; | 
					
						
							|  |  |  | 	snd_ctl_elem_value_t *val; | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	stream--; | 
					
						
							|  |  |  | 	if (stream < 0 || stream > 9) { | 
					
						
							|  |  |  | 		g_print("get_toggle_index (1)\n"); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	snd_ctl_elem_value_alloca(&val); | 
					
						
							|  |  |  | 	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	if (stream >= MAX_OUTPUT_CHANNELS) { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 		snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 		snd_ctl_elem_value_set_index(val, stream - MAX_OUTPUT_CHANNELS); | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME); | 
					
						
							|  |  |  | 		snd_ctl_elem_value_set_index(val, stream); | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	if ((err = snd_ctl_elem_read(ctl, val)) < 0) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	out = snd_ctl_elem_value_get_enumerated(val, 0); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	if (out >= MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS + 1) { | 
					
						
							|  |  |  | 		if (stream >= MAX_PCM_OUTPUT_CHANNELS || stream < MAX_SPDIF_CHANNELS) | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 			return 1; /* digital mixer */ | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	} else if (out >= MAX_INPUT_CHANNELS + 1) | 
					
						
							|  |  |  | 		return out - (MAX_INPUT_CHANNELS + 1) + 2; /* spdif left (=2) / right (=3) */ | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	else if (out >= 1) | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 		return out + spdif_channels + 1; /* analog (4-) */ | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; /* pcm */ | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void patchbay_update(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	int stream, tidx; | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	for (stream = 1; stream <= (MAX_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS); stream++) { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 		if (stream_active[stream - 1]) { | 
					
						
							|  |  |  | 			tidx = get_toggle_index(stream); | 
					
						
							|  |  |  | 			toggle_set(router_radio[stream - 1][tidx], TRUE); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void set_routes(int stream, int idx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int err; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	unsigned int out; | 
					
						
							|  |  |  | 	snd_ctl_elem_value_t *val; | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	stream--; | 
					
						
							|  |  |  | 	if (stream < 0 || stream > 9) { | 
					
						
							|  |  |  | 		g_print("set_routes (1)\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	if (! stream_active[stream]) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	out = 0; | 
					
						
							|  |  |  | 	if (idx == 1) | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 		out = MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS + 1; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	else if (idx == 2 || idx == 3)	/* S/PDIF left & right */ | 
					
						
							|  |  |  | 		out = idx + 7; /* 9-10 */ | 
					
						
							|  |  |  | 	else if (idx >= 4) /* analog */ | 
					
						
							|  |  |  | 		out = idx - 3; /* 1-8 */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	snd_ctl_elem_value_alloca(&val); | 
					
						
							|  |  |  | 	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	if (stream >= MAX_OUTPUT_CHANNELS) { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 		snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 		snd_ctl_elem_value_set_index(val, stream - MAX_OUTPUT_CHANNELS); | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME); | 
					
						
							|  |  |  | 		snd_ctl_elem_value_set_index(val, stream); | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	snd_ctl_elem_value_set_enumerated(val, 0, out); | 
					
						
							|  |  |  | 	if ((err = snd_ctl_elem_write(ctl, val)) < 0) | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | 		g_print("Multi track route write error: %s\n", snd_strerror(err)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void patchbay_toggled(GtkWidget *togglebutton, gpointer data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int stream = (long)data >> 16; | 
					
						
							|  |  |  | 	int what = (long)data & 0xffff; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (is_active(togglebutton)) | 
					
						
							|  |  |  | 		set_routes(stream, what); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | int patchbay_stream_is_active(int stream) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return stream_active[stream - 1]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | void patchbay_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	int nb_active_channels; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	snd_ctl_elem_value_t *val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	snd_ctl_elem_value_alloca(&val); | 
					
						
							|  |  |  | 	snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  | 	snd_ctl_elem_value_set_name(val, ANALOG_PLAYBACK_ROUTE_NAME); | 
					
						
							| 
									
										
										
										
											2004-02-24 19:05:44 +00:00
										 |  |  | 	memset (stream_active, 0, (MAX_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS) * sizeof(int)); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	nb_active_channels = 0; | 
					
						
							| 
									
										
										
										
											2003-06-04 13:46:49 +00:00
										 |  |  | 	for (i = 0; i < output_channels; i++) { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 		snd_ctl_elem_value_set_numid(val, 0); | 
					
						
							|  |  |  | 		snd_ctl_elem_value_set_index(val, i); | 
					
						
							|  |  |  | 		if (snd_ctl_elem_read(ctl, val) < 0) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		stream_active[i] = 1; | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 		nb_active_channels++; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	output_channels = nb_active_channels; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	snd_ctl_elem_value_set_name(val, SPDIF_PLAYBACK_ROUTE_NAME); | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	nb_active_channels = 0; | 
					
						
							| 
									
										
										
										
											2003-06-04 13:46:49 +00:00
										 |  |  | 	for (i = 0; i < spdif_channels; i++) { | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 		snd_ctl_elem_value_set_numid(val, 0); | 
					
						
							|  |  |  | 		snd_ctl_elem_value_set_index(val, i); | 
					
						
							|  |  |  |  		if (snd_ctl_elem_read(ctl, val) < 0) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 		stream_active[i + MAX_OUTPUT_CHANNELS] = 1; | 
					
						
							|  |  |  | 		nb_active_channels++; | 
					
						
							| 
									
										
										
										
											2001-06-13 18:41:38 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-03-05 09:10:01 +00:00
										 |  |  | 	spdif_channels = nb_active_channels; | 
					
						
							| 
									
										
										
										
											2000-10-29 21:51:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void patchbay_postinit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	patchbay_update(); | 
					
						
							|  |  |  | } |