Blame envy24control/patchbay.c

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