Blame envy24control/patchbay.c

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