Blame envy24control/mixer.c

Packit 427e91
/*****************************************************************************
Packit 427e91
   mixer.c - mixer 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
#include "midi.h"
Packit 427e91
#include "config.h"
Packit 427e91
Packit 427e91
#define	MULTI_PLAYBACK_SWITCH		"Multi Playback Switch"
Packit 427e91
#define MULTI_PLAYBACK_VOLUME		"Multi Playback Volume"
Packit 427e91
Packit 427e91
#define HW_MULTI_CAPTURE_SWITCH		"H/W Multi Capture Switch"
Packit 427e91
#define IEC958_MULTI_CAPTURE_SWITCH	"IEC958 Multi Capture Switch"
Packit 427e91
Packit 427e91
#define HW_MULTI_CAPTURE_VOLUME		"H/W Multi Capture Volume"
Packit 427e91
#define IEC958_MULTI_CAPTURE_VOLUME	"IEC958 Multi Capture Volume"
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_is_active[MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + \
Packit 427e91
				MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS];
Packit 427e91
extern int input_channels, output_channels, pcm_output_channels, spdif_channels, view_spdif_playback;
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
void mixer_update_stream(int stream, int vol_flag, int sw_flag)
Packit 427e91
{
Packit 427e91
	int err;
Packit 427e91
	
Packit 427e91
	if (! stream_is_active[stream - 1])
Packit 427e91
		return;
Packit 427e91
Packit 427e91
	if (vol_flag) {
Packit 427e91
		snd_ctl_elem_value_t *vol;
Packit 427e91
		int v[2];
Packit 427e91
		snd_ctl_elem_value_alloca(&vol;;
Packit 427e91
		snd_ctl_elem_value_set_interface(vol, SND_CTL_ELEM_IFACE_MIXER);
Packit 427e91
		snd_ctl_elem_value_set_name(vol, stream <= 10 ? MULTI_PLAYBACK_VOLUME : (stream <= 18 ? HW_MULTI_CAPTURE_VOLUME : IEC958_MULTI_CAPTURE_VOLUME));
Packit 427e91
		snd_ctl_elem_value_set_index(vol, stream <= 18 ? (stream - 1) % 10 : (stream - 1) % 18 );
Packit 427e91
		if ((err = snd_ctl_elem_read(ctl, vol)) < 0)
Packit 427e91
			g_print("Unable to read multi playback volume: %s\n", snd_strerror(err));
Packit 427e91
		v[0] = snd_ctl_elem_value_get_integer(vol, 0);
Packit 427e91
		v[1] = snd_ctl_elem_value_get_integer(vol, 1);
Packit 427e91
		if (v[0] != v[1])
Packit 427e91
			toggle_set(mixer_stereo_toggle[stream-1], FALSE);
Packit 427e91
		gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][0]), 96 - v[0]);
Packit 427e91
		gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][1]), 96 - v[1]);
Packit 427e91
		midi_controller((stream-1)*2,   v[0]);
Packit 427e91
		midi_controller((stream-1)*2+1, v[1]);
Packit 427e91
	}
Packit 427e91
	if (sw_flag) {
Packit 427e91
		snd_ctl_elem_value_t *sw;
Packit 427e91
		int v[2];
Packit 427e91
		snd_ctl_elem_value_alloca(&sw);
Packit 427e91
		snd_ctl_elem_value_set_interface(sw, SND_CTL_ELEM_IFACE_MIXER);
Packit 427e91
		snd_ctl_elem_value_set_name(sw, stream <= 10 ? MULTI_PLAYBACK_SWITCH : (stream <= 18 ? HW_MULTI_CAPTURE_SWITCH : IEC958_MULTI_CAPTURE_SWITCH));
Packit 427e91
		snd_ctl_elem_value_set_index(sw, stream <= 18 ? (stream - 1) % 10 : (stream - 1) % 18 );
Packit 427e91
		if ((err = snd_ctl_elem_read(ctl, sw)) < 0)
Packit 427e91
			g_print("Unable to read multi playback switch: %s\n", snd_strerror(err));
Packit 427e91
		v[0] = snd_ctl_elem_value_get_boolean(sw, 0);
Packit 427e91
		v[1] = snd_ctl_elem_value_get_boolean(sw, 1);
Packit 427e91
		if (v[0] != v[1])
Packit 427e91
			toggle_set(mixer_stereo_toggle[stream-1], FALSE);
Packit 427e91
		toggle_set(mixer_mute_toggle[stream-1][0], !v[0] ? TRUE : FALSE);
Packit 427e91
		toggle_set(mixer_mute_toggle[stream-1][1], !v[1] ? TRUE : FALSE);
Packit 427e91
		midi_button((stream-1)*2, v[0]);
Packit 427e91
		midi_button((stream-1)*2+1, v[1]);
Packit 427e91
	}
Packit 427e91
}
Packit 427e91
Packit 427e91
static void set_switch1(int stream, int left, int right)
Packit 427e91
{
Packit 427e91
	snd_ctl_elem_value_t *sw;
Packit 427e91
	int err, changed = 0;
Packit 427e91
	
Packit 427e91
	snd_ctl_elem_value_alloca(&sw);
Packit 427e91
	snd_ctl_elem_value_set_interface(sw, SND_CTL_ELEM_IFACE_MIXER);
Packit 427e91
	snd_ctl_elem_value_set_name(sw, stream <= 10 ? MULTI_PLAYBACK_SWITCH : (stream <= 18 ? HW_MULTI_CAPTURE_SWITCH : IEC958_MULTI_CAPTURE_SWITCH));
Packit 427e91
	snd_ctl_elem_value_set_index(sw, stream <= 18 ? (stream - 1) % 10 : (stream - 1) % 18 );
Packit 427e91
	if ((err = snd_ctl_elem_read(ctl, sw)) < 0)
Packit 427e91
		g_print("Unable to read multi switch: %s\n", snd_strerror(err));
Packit 427e91
	if (left >= 0 && left != snd_ctl_elem_value_get_boolean(sw, 0)) {
Packit 427e91
		snd_ctl_elem_value_set_boolean(sw, 0, left);
Packit 427e91
		changed = 1;
Packit 427e91
		midi_button((stream-1)*2, left);
Packit 427e91
	}
Packit 427e91
	if (right >= 0 && right != snd_ctl_elem_value_get_boolean(sw, 1)) {
Packit 427e91
		snd_ctl_elem_value_set_boolean(sw, 1, right);
Packit 427e91
		changed = 1;
Packit 427e91
		midi_button((stream-1)*2+1, right);
Packit 427e91
	}
Packit 427e91
	if (changed) {
Packit 427e91
		err = snd_ctl_elem_write(ctl, sw);
Packit 427e91
		if (err < 0)
Packit 427e91
			g_print("Unable to write multi switch: %s\n", snd_strerror(err));
Packit 427e91
	}
Packit 427e91
}
Packit 427e91
Packit 427e91
void mixer_toggled_mute(GtkWidget *togglebutton, gpointer data)
Packit 427e91
{
Packit 427e91
	int stream = (long)data >> 16;
Packit 427e91
	int button = (long)data & 1;
Packit 427e91
	int stereo = is_active(mixer_stereo_toggle[stream-1]) ? 1 : 0;
Packit 427e91
	int mute;
Packit 427e91
	int vol[2] = { -1, -1 };
Packit 427e91
	
Packit 427e91
	mute = is_active(mixer_mute_toggle[stream-1][button]);
Packit 427e91
	vol[button] = !mute;
Packit 427e91
	if (stereo) {
Packit 427e91
		toggle_set(mixer_mute_toggle[stream-1][button^1], mute);
Packit 427e91
		vol[button^1] = !mute;
Packit 427e91
	}
Packit 427e91
	set_switch1(stream, vol[0], vol[1]);
Packit 427e91
}
Packit 427e91
Packit 427e91
void mixer_set_mute(int stream, int left, int right)
Packit 427e91
{
Packit 427e91
	int stereo = is_active(mixer_stereo_toggle[stream-1]) ? 1 : 0;
Packit 427e91
	if (left >= 0 || stereo) {
Packit 427e91
		toggle_set(mixer_mute_toggle[stream-1][0], left ? TRUE : FALSE);
Packit 427e91
		if(stereo && left<0) left=right;
Packit 427e91
	}
Packit 427e91
	if (right >= 0 || stereo) {
Packit 427e91
		toggle_set(mixer_mute_toggle[stream-1][1], right ? TRUE : FALSE);
Packit 427e91
		if(stereo && right<0) right=left;
Packit 427e91
	}
Packit 427e91
	set_switch1(stream, left, right);
Packit 427e91
}
Packit 427e91
Packit 427e91
static void set_volume1(int stream, int left, int right)
Packit 427e91
{
Packit 427e91
	snd_ctl_elem_value_t *vol;
Packit 427e91
	int change = 0;
Packit 427e91
	int err;
Packit 427e91
	
Packit 427e91
	snd_ctl_elem_value_alloca(&vol;;
Packit 427e91
	snd_ctl_elem_value_set_interface(vol, SND_CTL_ELEM_IFACE_MIXER);
Packit 427e91
	snd_ctl_elem_value_set_name(vol, stream <= 10 ? MULTI_PLAYBACK_VOLUME : (stream <= 18 ? HW_MULTI_CAPTURE_VOLUME : IEC958_MULTI_CAPTURE_VOLUME));
Packit 427e91
	snd_ctl_elem_value_set_index(vol, stream <= 18 ? (stream - 1) % 10 : (stream - 1) % 18 );
Packit 427e91
	if ((err = snd_ctl_elem_read(ctl, vol)) < 0)
Packit 427e91
		g_print("Unable to read multi volume: %s\n", snd_strerror(err));
Packit 427e91
	if (left >= 0) {
Packit 427e91
		change |= (snd_ctl_elem_value_get_integer(vol, 0) != left);
Packit 427e91
		snd_ctl_elem_value_set_integer(vol, 0, left);
Packit 427e91
		midi_controller((stream-1)*2, left);
Packit 427e91
	}
Packit 427e91
	if (right >= 0) {
Packit 427e91
		change |= (snd_ctl_elem_value_get_integer(vol, 1) != right);
Packit 427e91
		snd_ctl_elem_value_set_integer(vol, 1, right);
Packit 427e91
		midi_controller((stream-1)*2+1, right);
Packit 427e91
	}
Packit 427e91
	if (change) {
Packit 427e91
		if ((err = snd_ctl_elem_write(ctl, vol)) < 0 && err != -EBUSY)
Packit 427e91
			g_print("Unable to write multi volume: %s\n", snd_strerror(err));
Packit 427e91
	}
Packit 427e91
}
Packit 427e91
Packit 427e91
void mixer_adjust(GtkAdjustment *adj, gpointer data)
Packit 427e91
{
Packit 427e91
	int stream = (long)data >> 16;
Packit 427e91
	int button = (long)data & 1;
Packit 427e91
	int stereo = is_active(mixer_stereo_toggle[stream-1]) ? 1 : 0;
Packit 427e91
	int vol[2] = { -1, -1 };
Packit 427e91
	
Packit 427e91
	vol[button] = 96 - adj->value;
Packit 427e91
	if (stereo) {
Packit 427e91
		gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][button ^ 1]), adj->value);
Packit 427e91
		vol[button ^ 1] = 96 - adj->value;
Packit 427e91
	}
Packit 427e91
	set_volume1(stream, vol[0], vol[1]);
Packit 427e91
}
Packit 427e91
Packit 427e91
int mixer_stream_is_active(int stream)
Packit 427e91
{
Packit 427e91
	return stream_is_active[stream - 1];
Packit 427e91
}
Packit 427e91
Packit 427e91
void mixer_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
	midi_maxstreams(sizeof(stream_is_active)/sizeof(stream_is_active[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
	memset (stream_is_active, 0, (MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS) * sizeof(int));
Packit 427e91
	snd_ctl_elem_value_set_name(val, MULTI_PLAYBACK_SWITCH);
Packit 427e91
	nb_active_channels = 0;
Packit 427e91
	for (i = 0; i < pcm_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_is_active[i] = 1;
Packit 427e91
		nb_active_channels++;
Packit 427e91
	}
Packit 427e91
	pcm_output_channels = nb_active_channels;
Packit 427e91
	for (i = MAX_PCM_OUTPUT_CHANNELS; i < MAX_PCM_OUTPUT_CHANNELS + 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_is_active[i] = 1;
Packit 427e91
	}
Packit 427e91
	snd_ctl_elem_value_set_name(val, HW_MULTI_CAPTURE_SWITCH);
Packit 427e91
	nb_active_channels = 0;
Packit 427e91
	for (i = 0; i < input_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_is_active[i + MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS] = 1;
Packit 427e91
		nb_active_channels++;
Packit 427e91
	}
Packit 427e91
	input_channels = nb_active_channels;
Packit 427e91
	snd_ctl_elem_value_set_name(val, IEC958_MULTI_CAPTURE_SWITCH);
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_is_active[i + MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS] = 1;
Packit 427e91
	}
Packit 427e91
}
Packit 427e91
Packit 427e91
void mixer_postinit(void)
Packit 427e91
{
Packit 427e91
	int stream;
Packit 427e91
Packit 427e91
	for (stream = 1; stream <= pcm_output_channels; stream++) {
Packit 427e91
		if (stream_is_active[stream - 1])
Packit 427e91
			mixer_update_stream(stream, 1, 1);
Packit 427e91
	}
Packit 427e91
	for (stream = MAX_PCM_OUTPUT_CHANNELS + 1; \
Packit 427e91
		stream <= MAX_PCM_OUTPUT_CHANNELS + spdif_channels; stream++) {
Packit 427e91
		if (stream_is_active[stream - 1] && view_spdif_playback)
Packit 427e91
			mixer_update_stream(stream, 1, 1);
Packit 427e91
	}
Packit 427e91
	for (stream = MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + 1; \
Packit 427e91
		stream <= MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + input_channels; stream++) {
Packit 427e91
		if (stream_is_active[stream - 1])
Packit 427e91
			mixer_update_stream(stream, 1, 1);
Packit 427e91
	}
Packit 427e91
	for (stream = MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS + 1; \
Packit 427e91
		stream <= MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS + spdif_channels; stream++) {
Packit 427e91
		if (stream_is_active[stream - 1])
Packit 427e91
			mixer_update_stream(stream, 1, 1);
Packit 427e91
	}
Packit 427e91
Packit 427e91
	config_restore_stereo();
Packit 427e91
}