| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  ALSA mixer console for Echoaudio soundcards. | 
					
						
							|  |  |  |  *  Copyright (C) 2003 Giuliano Pochini <pochini@shiny.it> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  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; version 2 of the License. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | #define EM_VERSION "%s Echomixer v" VERSION
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******
 | 
					
						
							|  |  |  |   Remove the "//" if you want to compile Echomixer in reverse mode. | 
					
						
							|  |  |  | *******/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //#define REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******
 | 
					
						
							|  |  |  |  Constants marked with *M* can be modified to customize the interface. | 
					
						
							|  |  |  | *******/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define BORDER		6			// *M* Inner border of GTK containers
 | 
					
						
							|  |  |  | #define SPACING		8			// *M* Spacing of control sections
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Graphic mixer constants
 | 
					
						
							|  |  |  | #define GM_BARWIDTH	5			// *M* Width of meters bars
 | 
					
						
							|  |  |  | #define XCELLBORDER	2			// *M* Space between the grid lines and the content of the cell
 | 
					
						
							|  |  |  | #define YCELLBORDER	2			// *M*
 | 
					
						
							|  |  |  | #define XCELLDIM	20			// *M* Width of the cell
 | 
					
						
							|  |  |  | #define YCELLDIM	32			// Height of the cell
 | 
					
						
							|  |  |  | #define XCELLTOT (1+XCELLBORDER*2+XCELLDIM)	// line + left border + cell + right border
 | 
					
						
							|  |  |  | #define YCELLTOT (1+YCELLBORDER*2+YCELLDIM)
 | 
					
						
							|  |  |  | #define XVOLUME (1+XCELLBORDER+3)		// Position of the volume slider
 | 
					
						
							|  |  |  | #define XMETER (1+XCELLBORDER-GM_BARWIDTH/2+13)	// Position of the VU bar
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // VU-meter constants
 | 
					
						
							|  |  |  | #define VU_XGRAF	30			// Left margin of the graphic
 | 
					
						
							|  |  |  | #define VU_YGRAF	20			// Top margin
 | 
					
						
							|  |  |  | #define VU_BARWIDTH	6			// *M* Width of VU-meters bars
 | 
					
						
							|  |  |  | #define VU_BARSEP	2			// *M* Space between bars
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define SHORTSTEP	1			// *M* 1dB (when the users moves a slider with cursor keys)
 | 
					
						
							|  |  |  | #define LONGSTEP	6			// *M* 6dB (with Page up/down or clicking the background)
 | 
					
						
							|  |  |  | #define DIGITAL_MODES	16			// Max number of digital modes
 | 
					
						
							|  |  |  | #define ECHO_CLOCKS	8			// Max number of clock sources
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define INPUT 0
 | 
					
						
							|  |  |  | #define OUTPUT 1
 | 
					
						
							|  |  |  | #define ECHO_MAXAUDIO_IOS	32		// The maximum number of inputs + outputs
 | 
					
						
							|  |  |  | #define ECHO_MAXAUDIOINPUTS	32		// Max audio input channels
 | 
					
						
							|  |  |  | #define ECHO_MAXAUDIOOUTPUTS	32		// Max audio output channels
 | 
					
						
							|  |  |  | #define ECHOGAIN_MUTED		(-128)		// Minimum possible gain
 | 
					
						
							|  |  |  | #define ECHOGAIN_MINOUT		(-128)		// Min output gain (unit is 1dB)
 | 
					
						
							|  |  |  | #define ECHOGAIN_MAXOUT		6		// Max output gain (unit is 1dB)
 | 
					
						
							|  |  |  | #define ECHOGAIN_MININP		(-50)		// Min input gain (unit is 0.5dB)
 | 
					
						
							|  |  |  | #define ECHOGAIN_MAXINP		50		// Max input gain (unit is 0.5dB)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // GTK+ adjustment widgets have the mininum value at top and maximum at bottom,
 | 
					
						
							|  |  |  | // position, but we need the opposite. This function puts the scale upside-down.
 | 
					
						
							|  |  |  | #define INVERT(x)	(ECHOGAIN_MINOUT+ECHOGAIN_MAXOUT-(x))
 | 
					
						
							|  |  |  | #define IN_INVERT(x)	(ECHOGAIN_MININP+ECHOGAIN_MAXINP-(x))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // REAL is for debugging only.
 | 
					
						
							|  |  |  | #define REAL
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | //#define CTLID_DEBUG(x) printf x
 | 
					
						
							|  |  |  | #define CTLID_DEBUG(x)
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define UI_DEBUG(x)
 | 
					
						
							|  |  |  | //#define UI_DEBUG(x) printf x
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <gtk/gtk.h>
 | 
					
						
							|  |  |  | #include <gdk/gdk.h>
 | 
					
						
							|  |  |  | #include <alsa/asoundlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char card[64], cardId[16]; | 
					
						
							|  |  |  | char dmodeName[DIGITAL_MODES][64], clocksrcName[DIGITAL_MODES][64], spdifmodeName[DIGITAL_MODES][64]; | 
					
						
							|  |  |  | int nLOut, nIn, fdIn, fdOut, nPOut, ClockMask; | 
					
						
							|  |  |  | int ndmodes, nclocksrc, nspdifmodes; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  | int GMixerRow, GMixerColumn, Gang, AutoClock; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  | int lineinId, pcmoutId, lineoutId, mixerId, vmixerId, p4InId, p4OutId, dmodeId; | 
					
						
							|  |  |  | int clocksrcId, spdifmodeId, vuswitchId, vumetersId, channelsId, phantomId, automuteId; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | int metersStreams, metersNumber, metersTypes; | 
					
						
							|  |  |  | int outvolCount; | 
					
						
							|  |  |  | int mouseY, mouseButton; | 
					
						
							|  |  |  | int dmodeVal, clocksrcVal, spdifmodeVal; | 
					
						
							|  |  |  | int VUwidth, VUheight, Mixwidth, Mixheight; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | #define DONT_DRAW (ECHOGAIN_MUTED-1)
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:24:09 +00:00
										 |  |  | #define DONT_CHANGE (1<<31)
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #define NOPOS 999999
 | 
					
						
							|  |  |  | struct geometry { | 
					
						
							|  |  |  |   int st;		// window status: 0 = hidden ; 1 = visible ; NOPOS = no stored setting
 | 
					
						
							|  |  |  |   GtkWidget *toggler;	// The toggle button that controls this window
 | 
					
						
							|  |  |  |   int x, y; | 
					
						
							|  |  |  |   int w, h; | 
					
						
							|  |  |  | } Mainw_geom, Miscw_geom, PVw_geom, LVw_geom, Mixerw_geom, Vmixerw_geom, VUw_geom, GMw_geom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // This structure contains the first and the last row of each section of the graphic mixer window
 | 
					
						
							|  |  |  | struct { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   int VmixerFirst, VmixerLast;	// Rows
 | 
					
						
							|  |  |  |   int LineOut;			// There is only one row
 | 
					
						
							|  |  |  |   int Inputs;			// Rows
 | 
					
						
							|  |  |  |   int Outputs;			// Columns
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | } GMixerSection; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct mixel { | 
					
						
							|  |  |  |   int id; | 
					
						
							|  |  |  |   int Gain; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | snd_ctl_t *ctlhandle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if __GNUC__ == 3		// gcc 2.x doesn't like unnamed unions inside structures
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct mixerControl_s { | 
					
						
							|  |  |  |   union {               // Currently selected channels
 | 
					
						
							|  |  |  |     int vchannel; | 
					
						
							|  |  |  |     int input; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   union {               // Number of channels
 | 
					
						
							|  |  |  |     int vchannels; | 
					
						
							|  |  |  |     int inputs; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   int output, outputs; | 
					
						
							|  |  |  |   int id; | 
					
						
							|  |  |  |   GtkWidget *window; | 
					
						
							|  |  |  |   GtkWidget *volume[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkWidget *label[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkObject *adj[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkWidget *outsel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   union { | 
					
						
							|  |  |  |     GtkWidget *inpsel[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |     GtkWidget *vchsel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   struct mixel mixer[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  | } mixerControl, vmixerControl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct mixerControl_s { | 
					
						
							|  |  |  |   int vchannel; | 
					
						
							|  |  |  |   int input; | 
					
						
							|  |  |  |   int vchannels; | 
					
						
							|  |  |  |   int inputs; | 
					
						
							|  |  |  |   int output, outputs; | 
					
						
							|  |  |  |   int id; | 
					
						
							|  |  |  |   GtkWidget *window; | 
					
						
							|  |  |  |   GtkWidget *volume[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkWidget *label[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkObject *adj[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkWidget *outsel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkWidget *inpsel[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   GtkWidget *vchsel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   struct mixel mixer[ECHO_MAXAUDIOOUTPUTS][ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  | } mixerControl, vmixerControl; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  | struct VolumeControl_s { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   int input, output;				// Currently selected channels
 | 
					
						
							|  |  |  |   int inputs, outputs; | 
					
						
							|  |  |  |   int id; | 
					
						
							|  |  |  |   GtkWidget *window; | 
					
						
							|  |  |  |   GtkWidget *volume[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkWidget *label[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   GtkObject *adj[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   int Gain[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  | } lineinControl, lineoutControl, pcmoutControl; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  | struct NominalLevelControl_s { | 
					
						
							|  |  |  |   int id; | 
					
						
							|  |  |  |   int Channels; | 
					
						
							|  |  |  |   char Level[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   GtkWidget *Button[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  | } NominalIn, NominalOut; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  | struct SwitchControl_s { | 
					
						
							|  |  |  |   int id; | 
					
						
							|  |  |  |   int value; | 
					
						
							|  |  |  |   GtkWidget *Button; | 
					
						
							|  |  |  | } PhantomPower, Automute; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | GtkWidget *clocksrc_menuitem[ECHO_CLOCKS]; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  | GtkWidget *dmodeOpt, *clocksrcOpt, *spdifmodeOpt, *phantomChkbutton, *autoclockChkbutton; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | GtkWidget *window, *Mainwindow, *Miscwindow, *LVwindow, *VUwindow, *GMwindow; | 
					
						
							|  |  |  | GtkWidget *VUdarea, *Mixdarea; | 
					
						
							|  |  |  | gint VUtimer, Mixtimer, clocksrctimer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GdkGC *gc=0; | 
					
						
							|  |  |  | static GdkPixmap *VUpixmap = NULL; | 
					
						
							|  |  |  | static GdkPixmap *Mixpixmap = NULL; | 
					
						
							|  |  |  | GdkFont *fnt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  | void Clock_source_activate(GtkWidget *widget, gpointer clk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int CountBits(int n) { | 
					
						
							|  |  |  |   int c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   c=0; | 
					
						
							|  |  |  |   while (n) { | 
					
						
							|  |  |  |     c++; | 
					
						
							|  |  |  |     n&=(n-1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return(c); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClampOutputVolume(int *v) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (*v>ECHOGAIN_MAXOUT) | 
					
						
							|  |  |  |     *v=ECHOGAIN_MAXOUT; | 
					
						
							|  |  |  |   else if (*v<ECHOGAIN_MINOUT) | 
					
						
							|  |  |  |     *v=ECHOGAIN_MINOUT; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClampInputVolume(int *v) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (*v>ECHOGAIN_MAXINP) | 
					
						
							|  |  |  |     *v=ECHOGAIN_MAXINP; | 
					
						
							|  |  |  |   else if (*v<ECHOGAIN_MININP) | 
					
						
							|  |  |  |     *v=ECHOGAIN_MININP; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // -128 dB means muted, that is -infinite dB
 | 
					
						
							|  |  |  | int Add_dB (int a, int b) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (a==ECHOGAIN_MINOUT || b==ECHOGAIN_MINOUT) | 
					
						
							|  |  |  |     return(ECHOGAIN_MINOUT); | 
					
						
							|  |  |  |   a+=b; | 
					
						
							|  |  |  |   if (a<ECHOGAIN_MINOUT) | 
					
						
							|  |  |  |     return(ECHOGAIN_MINOUT); | 
					
						
							|  |  |  |   return(a); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char *strOutGain(char *s, int g) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (g==ECHOGAIN_MINOUT) | 
					
						
							|  |  |  |     strcpy(s, "mute"); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     sprintf(s, "%+d", g); | 
					
						
							|  |  |  |   return(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Write an enumerated ALSA control
 | 
					
						
							|  |  |  | int SetEnum(int numid, int val) { | 
					
						
							|  |  |  |   int err; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, numid==clocksrcId ? SND_CTL_ELEM_IFACE_PCM : SND_CTL_ELEM_IFACE_CARD); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, numid); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_enumerated(control, 0, val); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_write(ctlhandle, control)) < 0) | 
					
						
							|  |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   return(err); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Read an enumerated ALSA control
 | 
					
						
							|  |  |  | int GetEnum(int numid) { | 
					
						
							|  |  |  |   int err, val; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, numid==clocksrcId ? SND_CTL_ELEM_IFACE_PCM : SND_CTL_ELEM_IFACE_CARD); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, numid); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_read(ctlhandle, control)) < 0) | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   val=snd_ctl_elem_value_get_enumerated(control, 0); | 
					
						
							|  |  |  |   return(val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Turn VU-meters on/off
 | 
					
						
							|  |  |  | void SetVUmeters(int onoff) { | 
					
						
							|  |  |  |   static signed char oncount=0; | 
					
						
							|  |  |  |   int err; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (onoff) | 
					
						
							|  |  |  |     oncount++; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     if (--oncount<0) | 
					
						
							|  |  |  |       oncount=0; | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, vuswitchId); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_integer(control, 0, !!oncount); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_write(ctlhandle, control)) < 0) { | 
					
						
							|  |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GetVUmeters(int *InLevel, int *InPeak, int *OutLevel, int *OutPeak, int *VirLevel, int *VirPeak) { | 
					
						
							|  |  |  |   int err, i, m; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, vumetersId); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   if ((err = snd_ctl_elem_read(ctlhandle, control)) < 0) { | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m=0; | 
					
						
							|  |  |  |   for (i=0; i<nLOut; i++) { | 
					
						
							|  |  |  |     OutLevel[i]=snd_ctl_elem_value_get_integer(control, m++); | 
					
						
							|  |  |  |     OutPeak[i]=snd_ctl_elem_value_get_integer(control, m++); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m=1*metersNumber*metersTypes; | 
					
						
							|  |  |  |   for (i=0; i<nIn; i++) { | 
					
						
							|  |  |  |     InLevel[i]=snd_ctl_elem_value_get_integer(control, m++); | 
					
						
							|  |  |  |     InPeak[i]=snd_ctl_elem_value_get_integer(control, m++); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   if (metersStreams==3) {	// Has PCM levels (Mia only) ?
 | 
					
						
							|  |  |  |     m=2*metersNumber*metersTypes; | 
					
						
							|  |  |  | #ifdef REAL
 | 
					
						
							|  |  |  |     for (i=0; i<nPOut; i++) { | 
					
						
							|  |  |  |       VirLevel[i]=snd_ctl_elem_value_get_integer(control, m++); | 
					
						
							|  |  |  |       VirPeak[i]=snd_ctl_elem_value_get_integer(control, m++); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |     for (i=0; i<nPOut; i++) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |       VirLevel[i]=i*5-100; | 
					
						
							|  |  |  |       VirPeak[i]=i*5-90; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Enable/disable widgets that control ADAT digital channels
 | 
					
						
							|  |  |  | void SetSensitivity(int enable) { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i=fdOut+2; i<nLOut; i++) { | 
					
						
							|  |  |  |     if (!enable && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mixerControl.outsel[i]))) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mixerControl.outsel[0]), TRUE); | 
					
						
							|  |  |  |     if (mixerId) | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(mixerControl.outsel[i], enable); | 
					
						
							|  |  |  |     if (vmixerId) { | 
					
						
							|  |  |  |       if (!enable && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vmixerControl.outsel[i]))) | 
					
						
							|  |  |  |         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vmixerControl.outsel[0]), TRUE); | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(vmixerControl.outsel[i], enable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (pcmoutId) { | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(pcmoutControl.label[i], enable); | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(pcmoutControl.volume[i], enable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Line-out control is always present
 | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(lineoutControl.label[i], enable); | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(lineoutControl.volume[i], enable); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   for (i=fdIn+2; i<nIn; i++) { | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(mixerControl.label[i], enable); | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(mixerControl.volume[i], enable); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!enable && mixerControl.input>=fdIn+2) | 
					
						
							|  |  |  |     mixerControl.input=0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else // REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Enable/disable widgets that control ADAT digital channels
 | 
					
						
							|  |  |  | void SetSensitivity(int enable) { | 
					
						
							|  |  |  |   int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i=fdIn+2; i<nIn; i++) { | 
					
						
							|  |  |  |     if (!enable && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mixerControl.inpsel[i]))) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mixerControl.inpsel[0]), TRUE); | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(mixerControl.inpsel[i], enable); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   for (i=fdOut+2; i<nLOut; i++) { | 
					
						
							|  |  |  |     if (mixerId) { | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(mixerControl.label[i], enable); | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(mixerControl.volume[i], enable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (vmixerId) { | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(vmixerControl.label[i], enable); | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(vmixerControl.volume[i], enable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (pcmoutId) { | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(pcmoutControl.label[i], enable); | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(pcmoutControl.volume[i], enable); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Line-out control is always present
 | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(lineoutControl.label[i], enable); | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(lineoutControl.volume[i], enable); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!enable && mixerControl.output>=fdOut+2) | 
					
						
							|  |  |  |     mixerControl.output=0; | 
					
						
							|  |  |  |   if (vmixerId && !enable && vmixerControl.output>=fdOut+2) | 
					
						
							|  |  |  |     vmixerControl.output=0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Read current control settings.
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  | int ReadControl(int *vol, int channels, int numid, int iface) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   int err, ch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |   snd_ctl_elem_id_set_interface(id, iface); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, numid); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_read(ctlhandle, control))<0) { | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |     return(err); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (ch=0; ch<channels; ch++) | 
					
						
							|  |  |  |     vol[ch]=snd_ctl_elem_value_get_integer(control, ch); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |   return(0); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  | void ReadNominalLevels(struct NominalLevelControl_s *NominalLevel) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   int err, i; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   snd_ctl_elem_id_set_numid(id, NominalLevel->id); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_read(ctlhandle, control))<0) | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   for (i=0; i<NominalLevel->Channels; i++) | 
					
						
							|  |  |  |     NominalLevel->Level[i]=snd_ctl_elem_value_get_integer(control, i); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | int SetMixerGain(struct mixel *mxl, int Gain) { | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, mxl->id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_integer(control, 0, Gain); | 
					
						
							|  |  |  |   if ((err = snd_ctl_elem_write(ctlhandle, control)) < 0) { | 
					
						
							|  |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |     return(err); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Read current (v)mixer settings.
 | 
					
						
							|  |  |  | void ReadMixer(struct mixerControl_s *mixer) { | 
					
						
							|  |  |  |   int err, in, out; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef REAL
 | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (out=0; out<mixer->outputs; out++) { | 
					
						
							|  |  |  |     for (in=0; in<mixer->inputs; in++) { | 
					
						
							|  |  |  |       snd_ctl_elem_id_set_numid(id, mixer->mixer[out][in].id); | 
					
						
							|  |  |  |       snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |       if ((err=snd_ctl_elem_read(ctlhandle, control))<0) | 
					
						
							|  |  |  |         printf("InitMixer - Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |       mixer->mixer[out][in].Gain=snd_ctl_elem_value_get_integer(control, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GetChannels(void) { | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   int err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_HWDEP); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, channelsId); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   if ((err = snd_ctl_elem_read(ctlhandle, control)) < 0) { | 
					
						
							|  |  |  |     printf("GetChannels() read error: %s\n", snd_strerror(err)); | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!nIn) {	// Only read the first time (mainly for debugging, see #define REAL)
 | 
					
						
							|  |  |  |     nIn=snd_ctl_elem_value_get_integer(control, 0);	// Number of input channels
 | 
					
						
							|  |  |  |     fdIn=snd_ctl_elem_value_get_integer(control, 1);	// First digital in (= number of analog input channels)
 | 
					
						
							|  |  |  |     nLOut=snd_ctl_elem_value_get_integer(control, 2);	// Number of output channels
 | 
					
						
							|  |  |  |     fdOut=snd_ctl_elem_value_get_integer(control, 3);	// First digital out
 | 
					
						
							|  |  |  |     nPOut=snd_ctl_elem_value_get_integer(control, 4);	// Number of virtual output channels (==nLOut on non-vmixer cards)
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   ClockMask=snd_ctl_elem_value_get_integer(control, 5);	// Bitmask of available input clocks
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | // Read what input clocks are valid and (de)activate the pop-down menu items accordingly
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | gint CheckInputs(gpointer unused) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   int clk, valid, source; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   GetChannels(); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   source=-1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Switch to internal if the source is not available
 | 
					
						
							|  |  |  |   if (AutoClock>=0 && !(ClockMask & (1<<clocksrcVal))) | 
					
						
							|  |  |  |     source=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (clk=0; clk<nclocksrc; clk++) { | 
					
						
							|  |  |  |     valid=!!(ClockMask & (1<<clk)); | 
					
						
							|  |  |  |     gtk_widget_set_sensitive(clocksrc_menuitem[clk], valid); | 
					
						
							|  |  |  |     if (clk==AutoClock && valid) | 
					
						
							|  |  |  |       source=AutoClock; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (source>=0 && source!=clocksrcVal) { | 
					
						
							|  |  |  |     // Set the clock source, but do not change the value of AutoClock
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     Clock_source_activate(clocksrc_menuitem[source], (gpointer)(long)(source|DONT_CHANGE)); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |     gtk_option_menu_set_history(GTK_OPTION_MENU(clocksrcOpt), clocksrcVal); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | void DrawBar(int x, int y, int level, int peak, int gain) { | 
					
						
							|  |  |  |   GdkColor Bars={0x00FF00, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Bars1={0x000000, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Peak={0x1BABFF, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Level={0xC0B000, 0, 0, 0}; | 
					
						
							|  |  |  |   int db; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   x=XMETER+XCELLTOT*x; | 
					
						
							|  |  |  |   y=YCELLTOT*y+YCELLBORDER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (level>ECHOGAIN_MUTED) { | 
					
						
							|  |  |  |     // Draw the "integer" part of the bar
 | 
					
						
							|  |  |  |     db=level>>2; | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Bars); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, x, y-db, GM_BARWIDTH, YCELLDIM+db); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Draw the antialiased part
 | 
					
						
							|  |  |  |     Bars1.pixel=(level&3) << (6 + 8);	// 4 levels (256/4==64==2^6) of green (2^8)
 | 
					
						
							|  |  |  |     if (Bars1.pixel) { | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &Bars1); | 
					
						
							|  |  |  |       gdk_draw_rectangle(Mixpixmap, gc, TRUE, x, y-db-1, GM_BARWIDTH, 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw the peak
 | 
					
						
							|  |  |  |   if (peak>ECHOGAIN_MUTED) { | 
					
						
							|  |  |  |     db=peak>>2; | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Peak); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, x, y-db, GM_BARWIDTH, 1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw the mixer gain
 | 
					
						
							|  |  |  |   if (gain>=ECHOGAIN_MUTED) { | 
					
						
							|  |  |  |     db=gain>>2; | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Level); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, x-XMETER+XVOLUME, y, 1, YCELLDIM); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, x-XMETER+XVOLUME-2, y-db, 5, 1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | // Draw the matrix mixer
 | 
					
						
							|  |  |  | gint DrawMixer(gpointer unused) { | 
					
						
							|  |  |  |   GdkRectangle update_rect; | 
					
						
							|  |  |  |   int InLevel[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   int InPeak[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   int OutLevel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   int OutPeak[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   int VirLevel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   int VirPeak[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   static int InClip[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   static int OutClip[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   char str[8]; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   int i, o, dB; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   GdkColor Grid={0x787878, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Labels={0x9694C4, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Hilight={0x000078, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Hilight2={0x600000, 0, 0, 0}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!Mixpixmap) | 
					
						
							|  |  |  |     return(TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   update_rect.x = 0; | 
					
						
							|  |  |  |   update_rect.y = 0; | 
					
						
							|  |  |  |   update_rect.width = Mixwidth; | 
					
						
							|  |  |  |   update_rect.height = Mixheight; | 
					
						
							|  |  |  |   GetVUmeters(InLevel, InPeak, OutLevel, OutPeak, VirLevel, VirPeak); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!gc) { | 
					
						
							|  |  |  |     gc=gdk_gc_new(gtk_widget_get_parent_window(Mixdarea)); | 
					
						
							|  |  |  |     for (i=0; i<nIn; i++) | 
					
						
							|  |  |  |       InClip[i]=0; | 
					
						
							|  |  |  |     for (i=0; i<nLOut; i++) | 
					
						
							|  |  |  |       OutClip[i]=0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gdk_draw_rectangle(Mixpixmap, Mixdarea->style->black_gc, TRUE, 0, 0, Mixwidth, Mixheight); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Highlight
 | 
					
						
							|  |  |  |   gdk_gc_set_foreground(gc, &Hilight); | 
					
						
							|  |  |  |   gdk_draw_rectangle(Mixpixmap, gc, TRUE, 0, YCELLTOT*mixerControl.input, XCELLTOT*(mixerControl.output+1), YCELLTOT); | 
					
						
							|  |  |  |   gdk_draw_rectangle(Mixpixmap, gc, TRUE, XCELLTOT*(mixerControl.output+1), YCELLTOT*mixerControl.input, XCELLTOT, Mixheight); | 
					
						
							|  |  |  |   if (vmixerId) { | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Hilight2); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, 0, YCELLTOT*(GMixerSection.VmixerFirst+vmixerControl.vchannel), XCELLTOT*(vmixerControl.output+1), YCELLTOT); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, XCELLTOT*(vmixerControl.output+1), YCELLTOT*(GMixerSection.VmixerFirst+vmixerControl.vchannel), XCELLTOT, Mixheight); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw the grid
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   gdk_gc_set_font(gc, fnt); | 
					
						
							|  |  |  |   // Horizontal lines and input channel labels
 | 
					
						
							|  |  |  |   for (i=0; i<GMixerSection.LineOut; i++) { | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Grid); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, 0, YCELLTOT*(i+1)-1, Mixwidth, 1); | 
					
						
							|  |  |  |     if (i<fdIn) | 
					
						
							|  |  |  |       sprintf(str, "A%d", i);		// Analog
 | 
					
						
							|  |  |  |     else if (i<nIn) | 
					
						
							|  |  |  |       sprintf(str, "D%d", i-fdIn);	// Digital
 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       sprintf(str, "V%d", i-nIn);	// Virtual
 | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Labels); | 
					
						
							|  |  |  |     gdk_draw_string(Mixpixmap, fnt, gc, 1, YCELLTOT*i+(YCELLTOT/2)+4, str); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   // Vertical lines and output channel labels
 | 
					
						
							|  |  |  |   for (o=0; o<nLOut; o++) { | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Grid); | 
					
						
							|  |  |  |     gdk_draw_rectangle(Mixpixmap, gc, TRUE, XCELLTOT*(o+1), 0, 1, Mixheight); | 
					
						
							|  |  |  |     if (o<fdOut) | 
					
						
							|  |  |  |       sprintf(str, "A%d", o); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       sprintf(str, "D%d", o-fdOut); | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Labels); | 
					
						
							|  |  |  |     gdk_draw_string(Mixpixmap, fnt, gc, XCELLTOT*(o+1)+(XCELLTOT/2)-6, YCELLTOT*GMixerSection.LineOut+YCELLTOT+8, str); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   gdk_draw_string(Mixpixmap, fnt, gc, 1, 8, "In"); | 
					
						
							|  |  |  |   gdk_draw_string(Mixpixmap, fnt, gc, 1, YCELLTOT*GMixerSection.LineOut+YCELLTOT+8, "Out"); | 
					
						
							|  |  |  |   gdk_gc_set_foreground(gc, &Grid); | 
					
						
							|  |  |  |   gdk_draw_rectangle(Mixpixmap, gc, TRUE, 0, YCELLTOT*(GMixerSection.LineOut+1)-1, Mixwidth, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw input levels and peaks
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   for (i=0; i<GMixerSection.Inputs; i++) | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |     DrawBar(0, i, InLevel[i], InPeak[i], DONT_DRAW); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Draw vchannels levels and peaks (Vmixer cards only)
 | 
					
						
							|  |  |  |   if (vmixerId) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |     for (i=0; i<vmixerControl.vchannels; i++) | 
					
						
							|  |  |  |       DrawBar(0, i+GMixerSection.VmixerFirst, VirLevel[i], VirPeak[i], DONT_DRAW); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw output levels, peaks and volumes
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   for (o=0; o<GMixerSection.Outputs; o++) | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |     DrawBar(o+1, GMixerSection.LineOut, OutLevel[o], OutPeak[o], lineoutControl.Gain[o]); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Draw monitor mixer elements
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   for (o=0; o<GMixerSection.Outputs; o++) { | 
					
						
							|  |  |  |     for (i=0; i<GMixerSection.Inputs; i++) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       dB=Add_dB(mixerControl.mixer[o][i].Gain, InLevel[i]); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |       DrawBar(o+1, i, dB, DONT_DRAW, mixerControl.mixer[o][i].Gain); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   // Draw vmixer elements (Vmixer cards only)
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   if (vmixerId) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     for (o=0; o<GMixerSection.Outputs; o++) | 
					
						
							| 
									
										
										
										
											2005-06-08 14:16:42 +00:00
										 |  |  |       for (i=0; i<vmixerControl.vchannels; i++) { | 
					
						
							|  |  |  |         dB=Add_dB(vmixerControl.mixer[o][i].Gain, VirLevel[i]); | 
					
						
							|  |  |  |         DrawBar(o+1, i+GMixerSection.VmixerFirst, dB, DONT_DRAW, vmixerControl.mixer[o][i].Gain); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gtk_widget_draw(Mixdarea, &update_rect); | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Draw the VU-meter
 | 
					
						
							|  |  |  | gint DrawVUmeters(gpointer unused) { | 
					
						
							|  |  |  |   GdkRectangle update_rect; | 
					
						
							|  |  |  |   int InLevel[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   int InPeak[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   int OutLevel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   int OutPeak[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   int VirLevel[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   int VirPeak[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   static int InClip[ECHO_MAXAUDIOINPUTS]; | 
					
						
							|  |  |  |   static int OutClip[ECHO_MAXAUDIOOUTPUTS]; | 
					
						
							|  |  |  |   int i, x, dB; | 
					
						
							|  |  |  |   char str[16]; | 
					
						
							|  |  |  |   GdkColor Selected={0xC86060, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Grid={0x9694C4, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Grid2={0x646383, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor dBValues={0x00B000, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor AnBars={0x00E0B8, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor DiBars={0x98E000, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor ClipPeak={0, 0, 0, 0}; | 
					
						
							|  |  |  |   GdkColor Peak={0x00FF00, 0, 0, 0}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!VUpixmap) | 
					
						
							|  |  |  |     return(TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   update_rect.x = 0; | 
					
						
							|  |  |  |   update_rect.y = 0; | 
					
						
							|  |  |  |   update_rect.width = VUwidth; | 
					
						
							|  |  |  |   update_rect.height = VUheight; | 
					
						
							|  |  |  |   GetVUmeters(InLevel, InPeak, OutLevel, OutPeak, VirLevel, VirPeak); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!gc) { | 
					
						
							|  |  |  |     gc=gdk_gc_new(gtk_widget_get_parent_window(VUdarea)); | 
					
						
							|  |  |  |     for (i=0; i<nIn; i++) | 
					
						
							|  |  |  |       InClip[i]=0; | 
					
						
							|  |  |  |     for (i=0; i<nLOut; i++) | 
					
						
							|  |  |  |       OutClip[i]=0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Clear the image
 | 
					
						
							|  |  |  |   gdk_draw_rectangle(VUpixmap, VUdarea->style->black_gc, TRUE, 0, 0, VUwidth, VUheight); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw the dB scale and the grid
 | 
					
						
							|  |  |  |   gdk_gc_set_font(gc, fnt); | 
					
						
							|  |  |  |   gdk_gc_set_foreground(gc, &Peak); | 
					
						
							|  |  |  |   gdk_draw_string(VUpixmap, fnt, gc, 2, VU_YGRAF-12+4, "  dB"); | 
					
						
							|  |  |  |   for (i=0; i<=120; i+=12) { | 
					
						
							|  |  |  |     sprintf(str, "%4d", -i); | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &dBValues); | 
					
						
							|  |  |  |     gdk_draw_string(VUpixmap, fnt, gc, 2, VU_YGRAF+i+4, str); | 
					
						
							|  |  |  |     gdk_gc_set_foreground(gc, &Grid); | 
					
						
							|  |  |  |     gdk_draw_rectangle(VUpixmap, gc, TRUE, VU_XGRAF, VU_YGRAF+i, VUwidth-VU_XGRAF, 1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   gdk_gc_set_foreground(gc, &Grid2); | 
					
						
							|  |  |  |   gdk_draw_rectangle(VUpixmap, gc, TRUE, VU_XGRAF, VU_YGRAF+128, VUwidth-VU_XGRAF, 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   x=VU_XGRAF+VU_BARSEP; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw inputs
 | 
					
						
							|  |  |  |   for (i=0; i<nIn; i++) { | 
					
						
							|  |  |  |     if (i<fdIn) | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &AnBars); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &DiBars); | 
					
						
							|  |  |  |     dB=InLevel[i]; | 
					
						
							|  |  |  |     gdk_draw_rectangle(VUpixmap, gc, TRUE, x, VU_YGRAF-dB, VU_BARWIDTH, 129+VU_YGRAF-(VU_YGRAF-dB)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dB=InPeak[i]; | 
					
						
							|  |  |  |     if (dB==0) | 
					
						
							|  |  |  |       InClip[i]=64; | 
					
						
							|  |  |  |     if (InClip[i]) { | 
					
						
							|  |  |  |       InClip[i]--; | 
					
						
							|  |  |  |       ClipPeak.pixel=(InClip[i]<<18)+((255-(InClip[i]*3))<<8); | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &ClipPeak); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &Peak); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gdk_draw_rectangle(VUpixmap, gc, TRUE, x, VU_YGRAF-dB, VU_BARWIDTH, 1); | 
					
						
							|  |  |  |     if (mixerControl.input==i) { | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &Selected); | 
					
						
							|  |  |  |       gdk_draw_rectangle(VUpixmap, gc, TRUE, x+1, VU_YGRAF+128+3, VU_BARWIDTH-2, 1); | 
					
						
							|  |  |  |       gdk_draw_rectangle(VUpixmap, gc, TRUE, x, VU_YGRAF+128+4, VU_BARWIDTH, 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     x+=VU_BARWIDTH+VU_BARSEP; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Draw outputs
 | 
					
						
							|  |  |  |   x+=VU_BARWIDTH+VU_BARSEP; | 
					
						
							|  |  |  |   for (i=0; i<nLOut; i++) { | 
					
						
							|  |  |  |     if (i<fdOut) | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &AnBars); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &DiBars); | 
					
						
							|  |  |  |     dB=OutLevel[i]; | 
					
						
							|  |  |  |     gdk_draw_rectangle(VUpixmap, gc, TRUE, x, VU_YGRAF-dB, VU_BARWIDTH, 129+VU_YGRAF-(VU_YGRAF-dB)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dB=OutPeak[i]; | 
					
						
							|  |  |  |     if (dB==0) | 
					
						
							|  |  |  |       OutClip[i]=64; | 
					
						
							|  |  |  |     if (OutClip[i]) { | 
					
						
							|  |  |  |       OutClip[i]--; | 
					
						
							|  |  |  |       ClipPeak.pixel=(OutClip[i]<<18)+((255-(OutClip[i]*3))<<8); | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &ClipPeak); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &Peak); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gdk_draw_rectangle(VUpixmap, gc, TRUE, x, VU_YGRAF-dB, VU_BARWIDTH, 1); | 
					
						
							|  |  |  |     if (mixerControl.output==i) { | 
					
						
							|  |  |  |       gdk_gc_set_foreground(gc, &Selected); | 
					
						
							|  |  |  |       gdk_draw_rectangle(VUpixmap, gc, TRUE, x+1, VU_YGRAF+128+3, VU_BARWIDTH-2, 1); | 
					
						
							|  |  |  |       gdk_draw_rectangle(VUpixmap, gc, TRUE, x, VU_YGRAF+128+4, VU_BARWIDTH, 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     x+=VU_BARWIDTH+VU_BARSEP; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gtk_widget_draw(VUdarea, &update_rect); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////////////////// GUI events
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Mixer_Output_selector_clicked(GtkWidget *widget, gpointer och) { | 
					
						
							|  |  |  |   int ich, val; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mixerControl.output==(int)och) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mixerControl.output=(int)och; | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   for (ich=0; ich<nIn; ich++) { | 
					
						
							|  |  |  |     val=INVERT(mixerControl.mixer[mixerControl.output][ich].Gain); | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(mixerControl.adj[ich]), (gfloat)val); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else // REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Mixer_Input_selector_clicked(GtkWidget *widget, gpointer ich) { | 
					
						
							|  |  |  |   int och, val; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   if (mixerControl.input==(int)(long)ich) | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   mixerControl.input=(int)(long)ich; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   for (och=0; och<nLOut; och++) { | 
					
						
							|  |  |  |     val=INVERT(mixerControl.mixer[och][mixerControl.input].Gain); | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(mixerControl.adj[och]), (gfloat)val); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif // REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gint Gmixer_button_press(GtkWidget *widget, GdkEventButton *event) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GMixerRow=(int)event->y/YCELLTOT; | 
					
						
							|  |  |  |   GMixerColumn=(int)event->x/XCELLTOT-1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   if (GMixerColumn<0 || GMixerColumn>=GMixerSection.Outputs) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   /* grab_focus must follow set_active because the latter causes
 | 
					
						
							|  |  |  |      Vmixer_*_selector_clicked() to be called and, in turn, | 
					
						
							|  |  |  |      Vmixer_volume_changed() which changes mixerControl.input | 
					
						
							|  |  |  |      (or .output in non-reverse mode). grab_focus then causes | 
					
						
							|  |  |  |      Vmixer_volume_clicked() to be called and that event handler | 
					
						
							|  |  |  |      finally sets the correct value of mixerControl.input */ | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   if (GMixerRow<GMixerSection.Inputs) { | 
					
						
							|  |  |  |     if (GMixerColumn!=mixerControl.output) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mixerControl.outsel[GMixerColumn]), TRUE); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     if (GMixerRow!=mixerControl.input) | 
					
						
							|  |  |  |       gtk_widget_grab_focus(GTK_WIDGET(mixerControl.volume[GMixerRow])); | 
					
						
							|  |  |  |   } else if (GMixerRow>=GMixerSection.VmixerFirst && GMixerRow<=GMixerSection.VmixerLast) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     if (GMixerColumn!=vmixerControl.output) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vmixerControl.outsel[GMixerColumn]), TRUE); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     if (GMixerRow!=vmixerControl.vchannel) | 
					
						
							|  |  |  |       gtk_widget_grab_focus(GTK_WIDGET(vmixerControl.volume[GMixerRow-GMixerSection.VmixerFirst])); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (event->button==1) { | 
					
						
							|  |  |  |     mouseY=event->y; | 
					
						
							|  |  |  |     mouseButton=1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else //REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gint Gmixer_button_press(GtkWidget *widget, GdkEventButton *event) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GMixerRow=(int)event->y/YCELLTOT; | 
					
						
							|  |  |  |   GMixerColumn=(int)event->x/XCELLTOT-1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   if (GMixerColumn<0 || GMixerColumn>=GMixerSection.Outputs) | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   // See the note above
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   if (GMixerRow<GMixerSection.Inputs) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     if (GMixerRow!=mixerControl.input) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mixerControl.inpsel[GMixerRow]), TRUE); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     if (GMixerColumn!=mixerControl.output) | 
					
						
							|  |  |  |       gtk_widget_grab_focus(GTK_WIDGET(mixerControl.volume[GMixerColumn])); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } else if (GMixerRow>=GMixerSection.VmixerFirst && GMixerRow<=GMixerSection.VmixerLast) { | 
					
						
							|  |  |  |     if (GMixerRow!=vmixerControl.vchannel) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(vmixerControl.vchsel[GMixerRow-GMixerSection.VmixerFirst]), TRUE); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     if (GMixerColumn!=vmixerControl.output) | 
					
						
							|  |  |  |       gtk_widget_grab_focus(GTK_WIDGET(vmixerControl.volume[GMixerColumn])); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (event->button==1) { | 
					
						
							|  |  |  |     mouseY=event->y; | 
					
						
							|  |  |  |     mouseButton=1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif //REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static gint Gmixer_button_release(GtkWidget *widget, GdkEventButton *event) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (event->state & GDK_BUTTON1_MASK) | 
					
						
							|  |  |  |     mouseButton=0; | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  | // Gets how many pixels the mouse pointer was moved of and updates
 | 
					
						
							|  |  |  | // the currently active mixer/vmixer/line_out control.
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | static gint Gmixer_motion_notify(GtkWidget *widget, GdkEventMotion *event) { | 
					
						
							|  |  |  |   int x, y; | 
					
						
							|  |  |  |   GdkModifierType state; | 
					
						
							|  |  |  |   float val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (event->is_hint) | 
					
						
							|  |  |  |     gdk_window_get_pointer(event->window, &x, &y, &state); | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     x=event->x; | 
					
						
							|  |  |  |     y=event->y; | 
					
						
							|  |  |  |     state=event->state; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   // Check if the button is still pressed because the release event can
 | 
					
						
							|  |  |  |   // fall in another window, so we may miss it. Ignore the event if there
 | 
					
						
							|  |  |  |   // isn't a backing pixmap or the user clicked an invalid cell. We also
 | 
					
						
							|  |  |  |   // have to check mouseButton because the button_press event may arrive
 | 
					
						
							|  |  |  |   // after the respective motion_notify event.
 | 
					
						
							|  |  |  |   if (!(state & GDK_BUTTON1_MASK) || !mouseButton || !Mixpixmap || GMixerColumn<0 || GMixerColumn>=GMixerSection.Outputs) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     mouseButton=0; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     return(TRUE); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   if (GMixerRow<GMixerSection.Inputs) { | 
					
						
							|  |  |  |     val=INVERT(mixerControl.mixer[mixerControl.output][mixerControl.input].Gain); | 
					
						
							|  |  |  |     val+=y-mouseY; | 
					
						
							|  |  |  |     mouseY=y; | 
					
						
							|  |  |  |     // Gtk already limits the range of "val"
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #ifdef REVERSE
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(mixerControl.adj[mixerControl.input]), (gfloat)val); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(mixerControl.adj[mixerControl.output]), (gfloat)val); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   } else if (GMixerRow>=GMixerSection.VmixerFirst && GMixerRow<=GMixerSection.VmixerLast) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     val=INVERT(vmixerControl.mixer[vmixerControl.output][vmixerControl.vchannel].Gain); | 
					
						
							|  |  |  |     val+=y-mouseY; | 
					
						
							|  |  |  |     mouseY=y; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #ifdef REVERSE
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(vmixerControl.adj[vmixerControl.vchannel]), (gfloat)val); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(vmixerControl.adj[vmixerControl.output]), (gfloat)val); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   } else if (GMixerRow==GMixerSection.LineOut) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |     val=INVERT(lineoutControl.Gain[GMixerColumn]); | 
					
						
							|  |  |  |     val+=y-mouseY; | 
					
						
							|  |  |  |     mouseY=y; | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(lineoutControl.adj[GMixerColumn]), (gfloat)val); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Monitor_volume_changed(GtkWidget *widget, gpointer cnl) { | 
					
						
							|  |  |  |   int val, rval, ch; | 
					
						
							|  |  |  |   int i, o; | 
					
						
							|  |  |  |   char str[16]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   UI_DEBUG(("Monitor_volume_changed()  %d %d\n",mixerControl.input,mixerControl.output)); | 
					
						
							|  |  |  |   val=rval=INVERT((int)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   ch=(int)(long)cnl; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  |   i=ch; | 
					
						
							|  |  |  |   o=mixerControl.output; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   i=mixerControl.input; | 
					
						
							|  |  |  |   o=ch; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Emulate the line-out volume if this card can't do it in hw.
 | 
					
						
							|  |  |  |   if (!lineoutId) { | 
					
						
							|  |  |  |     rval=Add_dB(val, lineoutControl.Gain[o]); | 
					
						
							|  |  |  |     ClampOutputVolume(&rval); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetMixerGain(&mixerControl.mixer[o][i], rval);	//@ we should restore the old adj position on error
 | 
					
						
							|  |  |  |   mixerControl.mixer[o][i].Gain=val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (Gang) { | 
					
						
							|  |  |  |     SetMixerGain(&mixerControl.mixer[o^1][i^1], rval); | 
					
						
							|  |  |  |     mixerControl.mixer[o^1][i^1].Gain=val; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gtk_label_set_text(GTK_LABEL(mixerControl.label[ch]), strOutGain(str, val)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Monitor_volume_clicked(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   mixerControl.input=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   mixerControl.output=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Gang_button_toggled(GtkWidget *widget, gpointer unused) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Gang=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PCM_volume_changed(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   char str[16]; | 
					
						
							|  |  |  |   int err, channel, val, rval; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   struct VolumeControl_s *vol; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   if ((int)(long)ch<ECHO_MAXAUDIOINPUTS) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     // Input
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     channel=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     vol=&lineinControl; | 
					
						
							|  |  |  |     rval=val=IN_INVERT((int)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  |     sprintf(str, "%+4.1f", 0.5*val); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     // Output
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     channel=(int)(long)ch-ECHO_MAXAUDIOINPUTS; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     vol=&pcmoutControl; | 
					
						
							|  |  |  |     val=rval=INVERT((int)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  |     pcmoutControl.Gain[channel]=val; | 
					
						
							|  |  |  |     // Emulate the line-out volume if this card can't do it in hw.
 | 
					
						
							|  |  |  |     if (!lineoutId) { | 
					
						
							|  |  |  |       rval=Add_dB(val, lineoutControl.Gain[channel]); | 
					
						
							|  |  |  |       ClampOutputVolume(&rval); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     strOutGain(str, val); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gtk_label_set_text(GTK_LABEL(vol->label[channel]), str); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, vol->id); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_read(ctlhandle, control))<0) { | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_integer(control, channel, rval); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_write(ctlhandle, control))<0) { | 
					
						
							|  |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     vol->Gain[channel]=val; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (Gang) | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(vol->adj[channel^1]), (gfloat)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Changes the PCM volume according to the current Line-out volume for non-vmixer cards
 | 
					
						
							|  |  |  | void UpdatePCMVolume(int outchannel) { | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   int err, val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, pcmoutId); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_read(ctlhandle, control))<0) | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   val=Add_dB(pcmoutControl.Gain[outchannel], lineoutControl.Gain[outchannel]); | 
					
						
							|  |  |  |   ClampOutputVolume(&val); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_integer(control, outchannel, val); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_write(ctlhandle, control))<0) | 
					
						
							|  |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Changes the monitor mixer volume according to the current Line-out volume for non-vmixer cards.
 | 
					
						
							|  |  |  | void UpdateMixerVolume(int outchannel) { | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   int err, val, ch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (ch=0; ch<nIn; ch++) { | 
					
						
							|  |  |  |     val=Add_dB(mixerControl.mixer[outchannel][ch].Gain, lineoutControl.Gain[outchannel]); | 
					
						
							|  |  |  |     ClampOutputVolume(&val); | 
					
						
							|  |  |  |     snd_ctl_elem_id_set_numid(id, mixerControl.mixer[outchannel][ch].id); | 
					
						
							|  |  |  |     snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |     snd_ctl_elem_value_set_integer(control, 0, val); | 
					
						
							|  |  |  |     if ((err = snd_ctl_elem_write(ctlhandle, control)) < 0) | 
					
						
							|  |  |  |       printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LineOut_volume_changed(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  |   char str[16]; | 
					
						
							|  |  |  |   int err, channel, val; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   channel=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   val=INVERT((int)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  |   lineoutControl.Gain[channel]=val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gtk_label_set_text(GTK_LABEL(lineoutControl.label[channel]), strOutGain(str, val)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (lineoutId) {	// If this card has the line-out control, use it
 | 
					
						
							|  |  |  |     snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |     snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |     snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |     snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |     snd_ctl_elem_id_set_numid(id, lineoutId); | 
					
						
							|  |  |  |     snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((err=snd_ctl_elem_read(ctlhandle, control))<0) | 
					
						
							|  |  |  |       printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |      snd_ctl_elem_value_set_integer(control, channel, val); | 
					
						
							|  |  |  |      if ((err=snd_ctl_elem_write(ctlhandle, control))<0) | 
					
						
							|  |  |  |        printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   } else {		// Otherwise we have to emulate it.
 | 
					
						
							|  |  |  |     UpdatePCMVolume(channel); | 
					
						
							|  |  |  |     UpdateMixerVolume(channel); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (Gang) | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(lineoutControl.adj[channel^1]), (gfloat)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Vmixer_volume_changed(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  |   char str[16]; | 
					
						
							|  |  |  |   int val, channel; | 
					
						
							|  |  |  |   int o, v; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   channel=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  |   v=channel; | 
					
						
							|  |  |  |   o=vmixerControl.output; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |   v=vmixerControl.vchannel; | 
					
						
							|  |  |  |   o=channel; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   val=INVERT((int)GTK_ADJUSTMENT(widget)->value); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetMixerGain(&vmixerControl.mixer[o][v], val); | 
					
						
							|  |  |  |   vmixerControl.mixer[o][v].Gain=val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (Gang) { | 
					
						
							|  |  |  |     SetMixerGain(&vmixerControl.mixer[o^1][v^1], val); | 
					
						
							|  |  |  |     vmixerControl.mixer[o^1][v^1].Gain=val; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   gtk_label_set_text(GTK_LABEL(vmixerControl.label[channel]), strOutGain(str, val)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Vmixer_volume_clicked(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   vmixerControl.vchannel=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   UI_DEBUG(("Vmixer_volume_clicked vch=%d\n",vmixerControl.vchannel)); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   vmixerControl.output=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   UI_DEBUG(("Vmixer_volume_clicked out=%d\n",vmixerControl.output)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Vmixer_output_selector_clicked(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  |   int c, val; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (vmixerControl.output==(int)ch) | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   vmixerControl.output=(int)ch; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   UI_DEBUG(("Vmixer_selector_clicked out=%d\n",vmixerControl.output)); | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   for (c=vmixerControl.vchannels-1; c>=0; c--) { | 
					
						
							|  |  |  |     val=INVERT(vmixerControl.mixer[vmixerControl.output][c].Gain); | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(vmixerControl.adj[c]), (gfloat)val); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Vmixer_vchannel_selector_clicked(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  |   int c, val; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   if (vmixerControl.vchannel==(int)(long)ch) | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   vmixerControl.vchannel=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   UI_DEBUG(("Vmixer_selector_clicked vch=%d\n",vmixerControl.vchannel)); | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |   for (c=vmixerControl.outputs-1; c>=0; c--) { | 
					
						
							|  |  |  |     val=INVERT(vmixerControl.mixer[c][vmixerControl.vchannel].Gain); | 
					
						
							|  |  |  |     gtk_adjustment_set_value(GTK_ADJUSTMENT(vmixerControl.adj[c]), (gfloat)val); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Nominal_level_toggled(GtkWidget *widget, gpointer ch) { | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							|  |  |  |   int err, val, channel; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   struct NominalLevelControl_s *NominalLevel; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   val=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   if ((int)(long)ch<ECHO_MAXAUDIOINPUTS) { | 
					
						
							|  |  |  |     channel=(int)(long)ch; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |     NominalLevel=&NominalIn; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     channel=(int)(long)ch-ECHO_MAXAUDIOINPUTS; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |     NominalLevel=&NominalOut; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   NominalLevel->Level[channel]=!val; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_set_numid(id, NominalLevel->id); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_read(ctlhandle, control))<0) | 
					
						
							|  |  |  |     printf("Control %s element read error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   snd_ctl_elem_value_set_integer(control, channel, !val);	// FALSE is +4
 | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_write(ctlhandle, control))<0) | 
					
						
							|  |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |   if (Gang) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(NominalLevel->Button[channel^1]), val); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  | void Switch_toggled(GtkWidget *widget, gpointer Ctl) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_value_t *control; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |   int err; | 
					
						
							|  |  |  |   struct SwitchControl_s *Switch=(struct SwitchControl_s *)Ctl; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_value_alloca(&control); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |   Switch->value=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_CARD); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |   snd_ctl_elem_id_set_numid(id, Switch->id); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   snd_ctl_elem_value_set_id(control, id); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |   snd_ctl_elem_value_set_integer(control, 0, Switch->value); | 
					
						
							|  |  |  |   if ((err=snd_ctl_elem_write(ctlhandle, control))<0) | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     printf("Control %s element write error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  | void AutoClock_toggled(GtkWidget *widget, gpointer unused) { | 
					
						
							|  |  |  |   char str[32]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { | 
					
						
							|  |  |  |     AutoClock=clocksrcVal; | 
					
						
							|  |  |  |     snprintf(str, 31, "Autoclock [%s]", clocksrcName[AutoClock]); | 
					
						
							|  |  |  |     str[31]=0; | 
					
						
							|  |  |  |     gtk_label_set_text(GTK_LABEL(GTK_BIN(widget)->child), str); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     AutoClock=-1; | 
					
						
							|  |  |  |     gtk_label_set_text(GTK_LABEL(GTK_BIN(widget)->child), "Autoclock"); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | void Digital_mode_activate(GtkWidget *widget, gpointer mode) { | 
					
						
							|  |  |  |   int adat; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   if (SetEnum(dmodeId, (int)(long)mode)<0) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     // Restore old value if it failed
 | 
					
						
							|  |  |  |     gtk_option_menu_set_history(GTK_OPTION_MENU(dmodeOpt), dmodeVal); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   dmodeVal=(int)(long)mode; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   // When I change the digital mode, the clock source can change too
 | 
					
						
							|  |  |  |   clocksrcVal=GetEnum(clocksrcId); | 
					
						
							|  |  |  |   gtk_option_menu_set_history(GTK_OPTION_MENU(clocksrcOpt), clocksrcVal); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   adat=!memcmp(dmodeName[dmodeVal], "ADAT", 4); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   SetSensitivity(adat); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   if (adat) { | 
					
						
							|  |  |  |     GMixerSection.Inputs=nIn; | 
					
						
							|  |  |  |     GMixerSection.Outputs=nLOut; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     GMixerSection.Inputs=fdIn+2;	// S/PDIF has only 2 channels
 | 
					
						
							|  |  |  |     GMixerSection.Outputs=fdOut+2; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Clock_source_activate(GtkWidget *widget, gpointer clk) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   unsigned int source; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   source=(unsigned int)(long)clk & 0xff; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   if (SetEnum(clocksrcId, source)<0) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     gtk_option_menu_set_history(GTK_OPTION_MENU(clocksrcOpt), clocksrcVal); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     clocksrcVal=(int)(long)clk & 0xff; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |     // Change only when the user triggers it
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     if (((int)(long)clk & DONT_CHANGE)==0 && AutoClock>=0) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |       AutoClock=clocksrcVal; | 
					
						
							|  |  |  |       AutoClock_toggled(autoclockChkbutton, NULL); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void SPDIF_mode_activate(GtkWidget *widget, gpointer mode) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |   SetEnum(spdifmodeId, (int)(long)mode);	// This one should never fail
 | 
					
						
							|  |  |  |   spdifmodeVal=(int)(long)mode; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create a new backing pixmap of the appropriate size
 | 
					
						
							|  |  |  | static gint VU_configure_event(GtkWidget *widget, GdkEventConfigure *event) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (VUpixmap) | 
					
						
							|  |  |  |     gdk_pixmap_unref(VUpixmap); | 
					
						
							|  |  |  |   VUpixmap=gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); | 
					
						
							|  |  |  |   gdk_draw_rectangle(VUpixmap, widget->style->black_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Redraw the screen from the backing pixmap
 | 
					
						
							|  |  |  | static gint VU_expose(GtkWidget *widget, GdkEventExpose *event) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (VUpixmap) | 
					
						
							|  |  |  |     gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], VUpixmap, | 
					
						
							|  |  |  |                     event->area.x, event->area.y, | 
					
						
							|  |  |  |                     event->area.x, event->area.y, | 
					
						
							|  |  |  |                     event->area.width, event->area.height); | 
					
						
							|  |  |  |   return(FALSE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Create a new backing pixmap of the appropriate size
 | 
					
						
							|  |  |  | static gint Gmixer_configure_event(GtkWidget *widget, GdkEventConfigure *event) { | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   if (Mixpixmap) | 
					
						
							|  |  |  |     gdk_pixmap_unref(Mixpixmap); | 
					
						
							|  |  |  |   Mixpixmap=gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); | 
					
						
							|  |  |  |   gdk_draw_rectangle(Mixpixmap, widget->style->black_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Redraw the screen from the backing pixmap
 | 
					
						
							|  |  |  | static gint Gmixer_expose(GtkWidget *widget, GdkEventExpose *event) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (Mixpixmap) | 
					
						
							|  |  |  |     gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], Mixpixmap, | 
					
						
							|  |  |  |                     event->area.x, event->area.y, | 
					
						
							|  |  |  |                     event->area.x, event->area.y, | 
					
						
							|  |  |  |                     event->area.width, event->area.height); | 
					
						
							|  |  |  |   return(FALSE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gint CloseWindow(GtkWidget *widget, GdkEvent *event, gpointer geom) { | 
					
						
							|  |  |  |   struct geometry *g=geom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gdk_window_get_root_origin(widget->window, &g->x, &g->y); | 
					
						
							|  |  |  |   gdk_window_get_size(widget->window, &g->w, &g->h); | 
					
						
							|  |  |  |   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->toggler), FALSE);	// This hides the window
 | 
					
						
							|  |  |  |   //gtk_widget_set_uposition(widget, g->x, g->y);
 | 
					
						
							|  |  |  |   return(TRUE);		// Do not destroy it
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gint Mainwindow_delete(GtkWidget *widget, GdkEvent *event, gpointer geom) { | 
					
						
							|  |  |  |   struct geometry *g=geom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (VUwindow) { | 
					
						
							|  |  |  |     gdk_window_get_root_origin(VUwindow->window, &VUw_geom.x, &VUw_geom.y); | 
					
						
							|  |  |  |     gtk_widget_destroy(VUwindow); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (GMwindow) { | 
					
						
							|  |  |  |     gdk_window_get_root_origin(GMwindow->window, &GMw_geom.x, &GMw_geom.y); | 
					
						
							|  |  |  |     gtk_widget_destroy(GMwindow); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   gdk_window_get_root_origin(Mainwindow->window, &g->x, &g->y); | 
					
						
							|  |  |  |   gtk_main_quit(); | 
					
						
							|  |  |  |   return(FALSE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gint VUwindow_delete(GtkWidget *widget, GdkEvent *event, gpointer geom) { | 
					
						
							|  |  |  |   struct geometry *g=geom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gdk_window_get_root_origin(widget->window, &g->x, &g->y); | 
					
						
							|  |  |  |   g->st=0; | 
					
						
							|  |  |  |   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->toggler), FALSE); | 
					
						
							|  |  |  |   return(FALSE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gint VUwindow_destroy(GtkWidget *widget, gpointer unused) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetVUmeters(0); | 
					
						
							|  |  |  |   gtk_timeout_remove(VUtimer); | 
					
						
							|  |  |  |   //@@@del gc and fnt
 | 
					
						
							|  |  |  |   VUwindow=0; | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gint GMwindow_delete(GtkWidget *widget, GdkEvent *event, gpointer geom) { | 
					
						
							|  |  |  |   struct geometry *g=geom; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   gdk_window_get_root_origin(widget->window, &g->x, &g->y); | 
					
						
							|  |  |  |   g->st=0; | 
					
						
							|  |  |  |   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->toggler), FALSE); | 
					
						
							|  |  |  |   return(FALSE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gint GMwindow_destroy(GtkWidget *widget, gpointer unused) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SetVUmeters(0); | 
					
						
							|  |  |  |   gtk_timeout_remove(Mixtimer); | 
					
						
							|  |  |  |   //@@@del gc and fnt
 | 
					
						
							|  |  |  |   GMwindow=0; | 
					
						
							|  |  |  |   return(TRUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void VUmeters_button_click(GtkWidget *widget, gpointer unused) { | 
					
						
							|  |  |  |   char str[64]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (VUwindow && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { | 
					
						
							|  |  |  |     VUw_geom.st=0; | 
					
						
							|  |  |  |     gtk_widget_destroy(VUwindow); | 
					
						
							|  |  |  |   } else if (!VUwindow && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { | 
					
						
							|  |  |  |     // Create VU-meter window
 | 
					
						
							|  |  |  |     VUwidth=VU_XGRAF+(VU_BARWIDTH+VU_BARSEP)*(nIn+nLOut+1)+VU_BARSEP; | 
					
						
							|  |  |  |     VUheight=160; | 
					
						
							|  |  |  |     SetVUmeters(1); | 
					
						
							|  |  |  |     VUwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |     sprintf(str, "%s VU-meters", cardId); | 
					
						
							|  |  |  |     gtk_window_set_title (GTK_WINDOW (VUwindow), str); | 
					
						
							|  |  |  |     gtk_window_set_wmclass(GTK_WINDOW(VUwindow), "vumeters", "Emixer"); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(VUwindow), "destroy", GTK_SIGNAL_FUNC(VUwindow_destroy), NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(VUwindow), "delete_event", GTK_SIGNAL_FUNC(VUwindow_delete), (gpointer)&VUw_geom); | 
					
						
							|  |  |  |     gtk_window_set_policy(GTK_WINDOW(VUwindow), FALSE, FALSE, TRUE); | 
					
						
							|  |  |  |     if (VUw_geom.st!=NOPOS) | 
					
						
							|  |  |  |       gtk_widget_set_uposition(VUwindow, VUw_geom.x, VUw_geom.y); | 
					
						
							|  |  |  |     gtk_widget_show(VUwindow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     VUdarea=gtk_drawing_area_new(); | 
					
						
							|  |  |  |     gtk_widget_set_events(VUdarea, GDK_EXPOSURE_MASK); | 
					
						
							|  |  |  |     gtk_drawing_area_size(GTK_DRAWING_AREA(VUdarea), VUwidth, VUheight); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(VUwindow), VUdarea); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gtk_widget_show(VUdarea); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(VUdarea), "expose_event", (GtkSignalFunc)VU_expose, NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(VUdarea), "configure_event", (GtkSignalFunc)VU_configure_event, NULL); | 
					
						
							|  |  |  |     VUtimer=gtk_timeout_add(30, DrawVUmeters, 0);	// The hw updates the meters about 30 times/s
 | 
					
						
							|  |  |  |     gdk_window_clear_area(VUdarea->window, 0, 0, VUwidth, VUheight); | 
					
						
							|  |  |  |     VUw_geom.st=1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GMixer_button_click(GtkWidget *widget, gpointer unused) { | 
					
						
							|  |  |  |   char str[64]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (GMwindow && !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { | 
					
						
							|  |  |  |     GMw_geom.st=0; | 
					
						
							|  |  |  |     gtk_widget_destroy(GMwindow); | 
					
						
							|  |  |  |   } else if (!GMwindow && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { | 
					
						
							|  |  |  |     // Create graphic mixer window
 | 
					
						
							|  |  |  |     Mixwidth=XCELLTOT*(nLOut+1); | 
					
						
							|  |  |  |     Mixheight=YCELLTOT*(GMixerSection.LineOut+1)+9; | 
					
						
							|  |  |  |     SetVUmeters(1); | 
					
						
							|  |  |  |     GMwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |     sprintf(str, "%s Mixer", cardId); | 
					
						
							|  |  |  |     gtk_window_set_title (GTK_WINDOW (GMwindow), str); | 
					
						
							|  |  |  |     gtk_window_set_wmclass(GTK_WINDOW(GMwindow), "gridmixer", "Emixer"); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(GMwindow), "destroy", GTK_SIGNAL_FUNC(GMwindow_destroy), NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(GMwindow), "delete_event", GTK_SIGNAL_FUNC(GMwindow_delete), (gpointer)&GMw_geom); | 
					
						
							|  |  |  |     gtk_window_set_policy(GTK_WINDOW(GMwindow), FALSE, FALSE, TRUE); | 
					
						
							|  |  |  |     if (GMw_geom.st!=NOPOS) | 
					
						
							|  |  |  |       gtk_widget_set_uposition(GMwindow, GMw_geom.x, GMw_geom.y); | 
					
						
							|  |  |  |     gtk_widget_show(GMwindow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Mixdarea=gtk_drawing_area_new(); | 
					
						
							|  |  |  |     gtk_widget_set_events(Mixdarea, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); | 
					
						
							|  |  |  |     gtk_drawing_area_size(GTK_DRAWING_AREA(Mixdarea), Mixwidth, Mixheight); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(GMwindow), Mixdarea); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gtk_widget_show(Mixdarea); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(Mixdarea), "expose_event", (GtkSignalFunc)Gmixer_expose, NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(Mixdarea), "configure_event", (GtkSignalFunc)Gmixer_configure_event, NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(Mixdarea), "motion_notify_event", (GtkSignalFunc)Gmixer_motion_notify, NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(Mixdarea), "button_press_event", (GtkSignalFunc)Gmixer_button_press, NULL); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(Mixdarea), "button_release_event", (GtkSignalFunc)Gmixer_button_release, NULL); | 
					
						
							|  |  |  |     Mixtimer=gtk_timeout_add(30, DrawMixer, 0);		// The hw updates the meters about 30 times/s
 | 
					
						
							|  |  |  |     gdk_window_clear_area(Mixdarea->window, 0, 0, Mixwidth, Mixheight); | 
					
						
							|  |  |  |     GMw_geom.st=1; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ToggleWindow(GtkWidget *widget, gpointer window) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) | 
					
						
							|  |  |  |     gtk_widget_show(GTK_WIDGET(window)); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     gtk_widget_hide(GTK_WIDGET(window)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  | // Scan all controls and sets up the structures needed to access them.
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | int OpenControls(const char *card, const char *cardname) { | 
					
						
							|  |  |  |   int err, i, o; | 
					
						
							|  |  |  |   int numid, count, items, item; | 
					
						
							|  |  |  |   snd_hctl_t *handle; | 
					
						
							|  |  |  |   snd_hctl_elem_t *elem; | 
					
						
							|  |  |  |   snd_ctl_elem_id_t *id; | 
					
						
							|  |  |  |   snd_ctl_elem_info_t *info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pcmoutId=lineoutId=vmixerId=p4InId=p4OutId=dmodeId=clocksrcId=spdifmodeId=vuswitchId=vumetersId=mixerId=0; | 
					
						
							|  |  |  |   memset(&vmixerControl, 0, sizeof(vmixerControl)); | 
					
						
							|  |  |  |   memset(&mixerControl, 0, sizeof(mixerControl)); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   memset(&lineoutControl, 0, sizeof(struct VolumeControl_s)); | 
					
						
							|  |  |  |   memset(&lineinControl, 0, sizeof(struct VolumeControl_s)); | 
					
						
							|  |  |  |   memset(&pcmoutControl, 0, sizeof(struct VolumeControl_s)); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   ndmodes=nclocksrc=nspdifmodes=0; | 
					
						
							|  |  |  |   snd_ctl_elem_id_alloca(&id); | 
					
						
							|  |  |  |   snd_ctl_elem_info_alloca(&info); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((err=snd_hctl_open(&handle, card, 0))<0) { | 
					
						
							|  |  |  |     printf("Control %s open error: %s", card, snd_strerror(err)); | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if ((err=snd_hctl_load(handle))<0) { | 
					
						
							|  |  |  |     printf("Control %s local error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   for (elem=snd_hctl_first_elem(handle); elem; elem=snd_hctl_elem_next(elem)) { | 
					
						
							|  |  |  |     if ((err=snd_hctl_elem_info(elem, info))<0) { | 
					
						
							|  |  |  |       printf("Control %s snd_hctl_elem_info error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |       return err; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (snd_ctl_elem_info_is_inactive(info)) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     snd_hctl_elem_get_id(elem, id); | 
					
						
							|  |  |  |     numid=snd_ctl_elem_id_get_numid(id); | 
					
						
							|  |  |  |     count=snd_ctl_elem_info_get_count(info); | 
					
						
							|  |  |  |     if (!strcmp("Monitor Mixer Volume", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       if (!mixerId) { | 
					
						
							|  |  |  |         mixerId=numid; | 
					
						
							|  |  |  |         CTLID_DEBUG(("First Mixer id=%d\n", mixerId)); | 
					
						
							|  |  |  |         mixerControl.outputs=snd_ctl_elem_info_get_dimension(info, 0); | 
					
						
							|  |  |  |         mixerControl.inputs=snd_ctl_elem_info_get_dimension(info, 1); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (!strcmp("VMixer Volume", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       if (!vmixerId) { | 
					
						
							|  |  |  |         vmixerId=vmixerControl.id=numid; | 
					
						
							|  |  |  |         CTLID_DEBUG(("First Vmixer id=%d\n", vmixerId)); | 
					
						
							|  |  |  |         vmixerControl.outputs=snd_ctl_elem_info_get_dimension(info, 0); | 
					
						
							|  |  |  |         vmixerControl.vchannels=snd_ctl_elem_info_get_dimension(info, 1); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (!strcmp("PCM Playback Volume", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       pcmoutId=pcmoutControl.id=numid; | 
					
						
							|  |  |  |       CTLID_DEBUG(("PCM Playback Volume id=%d [%d]\n", pcmoutId, count)); | 
					
						
							|  |  |  |     } else if (!strcmp("Line Playback Volume", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       lineoutId=numid; | 
					
						
							|  |  |  |       CTLID_DEBUG(("Line Volume id=%d\n", lineoutId)); | 
					
						
							|  |  |  |     } else if (!strcmp("Line Capture Volume", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       lineinId=lineinControl.id=numid; | 
					
						
							|  |  |  |       CTLID_DEBUG(("Capture Volume id=%d [%d]\n", lineinId, count)); | 
					
						
							|  |  |  |     } else if (!strcmp("Line Playback Switch (-10dBV)", snd_ctl_elem_id_get_name(id))) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |       p4OutId=NominalOut.id=numid; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       CTLID_DEBUG(("Playback nominal id=%d [%d]\n", p4OutId, count)); | 
					
						
							|  |  |  |     } else if (!strcmp("Line Capture Switch (-10dBV)", snd_ctl_elem_id_get_name(id))) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |       p4InId=NominalIn.id=numid; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       CTLID_DEBUG(("Capture nominal id=%d [%d]\n", p4InId, count)); | 
					
						
							|  |  |  |     } else if (!strcmp("Digital mode Switch", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       dmodeId=numid; | 
					
						
							|  |  |  |       items=snd_ctl_elem_info_get_items(info); | 
					
						
							|  |  |  |       ndmodes=items; | 
					
						
							|  |  |  |       for (item=0; item<items; item++) { | 
					
						
							|  |  |  |         snd_ctl_elem_info_set_item(info, item); | 
					
						
							|  |  |  |         if ((err=snd_hctl_elem_info(elem, info)) < 0) { | 
					
						
							|  |  |  |           printf("Control %s element info error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |           exit(err); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         strncpy(dmodeName[item], snd_ctl_elem_info_get_item_name(info), 63); | 
					
						
							|  |  |  |         dmodeName[item][63]=0; | 
					
						
							|  |  |  |         CTLID_DEBUG(("Digital Mode id=%d item #%u '%s'\n", numid, item, snd_ctl_elem_info_get_item_name(info))); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (!strcmp("Sample Clock Source", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       clocksrcId=numid; | 
					
						
							|  |  |  |       items=snd_ctl_elem_info_get_items(info); | 
					
						
							|  |  |  |       nclocksrc=items; | 
					
						
							|  |  |  |       for (item=0; item<items; item++) { | 
					
						
							|  |  |  |         snd_ctl_elem_info_set_item(info, item); | 
					
						
							|  |  |  |         if ((err=snd_hctl_elem_info(elem, info))<0) { | 
					
						
							|  |  |  |           printf("Control %s element info error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |           exit(err); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         strncpy(clocksrcName[item], snd_ctl_elem_info_get_item_name(info), 63); | 
					
						
							|  |  |  |         clocksrcName[item][63]=0; | 
					
						
							|  |  |  |         CTLID_DEBUG(("Clock source id=%d item #%u '%s'\n", numid, item, snd_ctl_elem_info_get_item_name(info))); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (!strcmp("S/PDIF mode Switch", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       spdifmodeId=numid; | 
					
						
							|  |  |  |       items=snd_ctl_elem_info_get_items(info); | 
					
						
							|  |  |  |       nspdifmodes=items; | 
					
						
							|  |  |  |       for (item=0; item<items; item++) { | 
					
						
							|  |  |  |         snd_ctl_elem_info_set_item(info, item); | 
					
						
							|  |  |  |         if ((err=snd_hctl_elem_info(elem, info)) < 0) { | 
					
						
							|  |  |  |           printf("Control %s element info error: %s\n", card, snd_strerror(err)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         strncpy(spdifmodeName[item], snd_ctl_elem_info_get_item_name(info), 63); | 
					
						
							|  |  |  |         spdifmodeName[item][63]=0; | 
					
						
							|  |  |  |         CTLID_DEBUG(("S/PDIF Mode id=%d item #%u '%s'\n", numid, item, snd_ctl_elem_info_get_item_name(info))); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else if (!strcmp("Phantom power Switch", snd_ctl_elem_id_get_name(id))) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |       phantomId=PhantomPower.id=numid; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       CTLID_DEBUG(("Phantom power Switch id=%d\n", numid)); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |     } else if (!strcmp("Digital Capture Switch (automute)", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       automuteId=Automute.id=numid; | 
					
						
							|  |  |  |       CTLID_DEBUG(("Automute Switch id=%d\n", numid)); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } else if (!strcmp("VU-meters Switch", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       vuswitchId=numid; | 
					
						
							|  |  |  |       CTLID_DEBUG(("VU-meter switch id=%d\n", numid)); | 
					
						
							|  |  |  |     } else if (!strcmp("VU-meters", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       vumetersId=numid; | 
					
						
							|  |  |  |       metersStreams=snd_ctl_elem_info_get_dimension(info, 0);	// 2 or 3: output, input and (vmixer cards only) pcm
 | 
					
						
							|  |  |  |       metersNumber=snd_ctl_elem_info_get_dimension(info, 1);	// Number of channels
 | 
					
						
							|  |  |  |       metersTypes=snd_ctl_elem_info_get_dimension(info, 2);	// 2: level and peak
 | 
					
						
							|  |  |  |       CTLID_DEBUG(("VU-meters id=%d\n", numid)); | 
					
						
							|  |  |  |     } else if (!strcmp("Channels info", snd_ctl_elem_id_get_name(id))) { | 
					
						
							|  |  |  |       channelsId=numid; | 
					
						
							|  |  |  |       CTLID_DEBUG(("Channels info id=%d\n", numid)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   GetChannels(); | 
					
						
							|  |  |  |   CTLID_DEBUG(("Input channels = %d (analog=%d digital=%d)\n", nIn, fdIn, nIn-fdIn)); | 
					
						
							|  |  |  |   CTLID_DEBUG(("Output channels = %d (analog=%d digital=%d)\n", nLOut, fdOut, nLOut-fdOut)); | 
					
						
							|  |  |  |   CTLID_DEBUG(("PCM channels out = %d\n", nPOut)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef REAL
 | 
					
						
							|  |  |  | vmixerId=1000; | 
					
						
							|  |  |  | vmixerControl.vchannels=12; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  | vmixerControl.outputs=mixerControl.outputs=nLOut=10; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | metersStreams=3; | 
					
						
							|  |  |  | metersNumber=16; | 
					
						
							|  |  |  | metersTypes=2; | 
					
						
							|  |  |  | nPOut=12; | 
					
						
							|  |  |  | fdOut=2; | 
					
						
							|  |  |  | nIn=10; | 
					
						
							|  |  |  | fdIn=2; | 
					
						
							|  |  |  | printf("nIn=%d fdIn=%d nLOut=%d nPOut=%d fdOut=%d\n", nIn,fdIn,nLOut,nPOut, fdOut); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mixerId && (mixerControl.inputs!=nIn || mixerControl.outputs!=nLOut)) { | 
					
						
							|  |  |  |     printf("** Error - Mixer/channels mismatch !!  nIn=%d mnIn=%d    nLOut=%d mnLOut=%d\n", nIn, mixerControl.inputs, nLOut, mixerControl.outputs); | 
					
						
							|  |  |  |     return(1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (lineoutId && !vmixerId) | 
					
						
							|  |  |  |     printf("** Warning - Vmixer cards without LineOut volume control are not supported !\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (vmixerId) { | 
					
						
							|  |  |  |     if (vmixerControl.vchannels!=nPOut || vmixerControl.outputs!=nLOut) { | 
					
						
							|  |  |  |       printf("** Error - vmixer/channels mismatch:  vmp=%d npo=%d    vmo=%d nlo=%d !!\n", vmixerControl.vchannels, nPOut, vmixerControl.outputs, nLOut); | 
					
						
							|  |  |  |       return(1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |   if (p4InId) | 
					
						
							|  |  |  |     NominalIn.Channels=fdIn; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (p4OutId) | 
					
						
							|  |  |  |     NominalOut.Channels=fdOut; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   //@ Assumes all mixer and vmixer controls are contiguous
 | 
					
						
							|  |  |  |   if (mixerId) | 
					
						
							|  |  |  |     for (o=0, numid=mixerId; o<nLOut; o++) { | 
					
						
							|  |  |  |       for (i=0; i<nIn; i++) { | 
					
						
							|  |  |  |         mixerControl.mixer[o][i].id=numid++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (vmixerId) | 
					
						
							|  |  |  |     for (o=0, numid=vmixerId; o<vmixerControl.outputs; o++) { | 
					
						
							|  |  |  |       for (i=0; i<vmixerControl.vchannels; i++) { | 
					
						
							|  |  |  |         vmixerControl.mixer[o][i].id=numid++; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   snd_hctl_close(handle); | 
					
						
							|  |  |  |   return(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char *argv[]) { | 
					
						
							|  |  |  |   gchar str[256]; | 
					
						
							|  |  |  |   GtkWidget *hbox, *vbox; | 
					
						
							|  |  |  |   GtkWidget *mainbox; | 
					
						
							|  |  |  |   GtkWidget *vbsel, *frame, *button; | 
					
						
							|  |  |  |   GtkWidget *label, *menu, *menuitem; | 
					
						
							|  |  |  |   GSList *bgroup; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |   int err, i, o, n, cardnum, value; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   char hwname[8], cardname[32], load, save; | 
					
						
							|  |  |  |   snd_ctl_card_info_t *hw_info; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   load=save=1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Scans all installed cards
 | 
					
						
							|  |  |  |   snd_ctl_card_info_alloca(&hw_info); | 
					
						
							|  |  |  |   cardnum=-1; | 
					
						
							|  |  |  |   ctlhandle=0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (argc>1) | 
					
						
							|  |  |  |     cardnum=atoi(argv[1])-1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (snd_card_next(&cardnum)>=0 && cardnum>=0) { | 
					
						
							|  |  |  |     sprintf(hwname, "hw:%d", cardnum); | 
					
						
							|  |  |  |     if ((err=snd_ctl_open(&ctlhandle, hwname, 0))<0) { | 
					
						
							|  |  |  |       printf("snd_ctl_open(%s) Error: %s\n", hwname, snd_strerror(err)); | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ((err=snd_ctl_card_info(ctlhandle, hw_info))>=0) { | 
					
						
							| 
									
										
										
										
											2005-07-26 12:57:08 +00:00
										 |  |  |       if (!strncmp(snd_ctl_card_info_get_driver(hw_info), "Echo_", 5)) { | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |         strncpy(card, hwname, 7); | 
					
						
							|  |  |  |         hwname[7]=0; | 
					
						
							|  |  |  |         strncpy(cardname, snd_ctl_card_info_get_name(hw_info), 31); | 
					
						
							|  |  |  |         cardname[31]=0; | 
					
						
							|  |  |  |         strncpy(cardId, snd_ctl_card_info_get_name(hw_info), 15); | 
					
						
							|  |  |  |         cardId[15]=0; | 
					
						
							|  |  |  |         CTLID_DEBUG(("Card found: %s  (%s)\n", snd_ctl_card_info_get_longname(hw_info), hwname)); | 
					
						
							|  |  |  | /*printf("card       = %d\n", snd_ctl_card_info_get_card(hw_info));
 | 
					
						
							|  |  |  | printf("id         = %s\n", snd_ctl_card_info_get_id(hw_info)); | 
					
						
							|  |  |  | printf("driver     = %s\n", snd_ctl_card_info_get_driver(hw_info)); | 
					
						
							|  |  |  | printf("name       = %s\n", snd_ctl_card_info_get_name(hw_info)); | 
					
						
							|  |  |  | printf("longname   = %s\n", snd_ctl_card_info_get_longname(hw_info)); | 
					
						
							|  |  |  | printf("mixername  = %s\n", snd_ctl_card_info_get_mixername(hw_info)); | 
					
						
							|  |  |  | printf("components = %s\n", snd_ctl_card_info_get_components(hw_info));*/ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       printf("snd_ctl_card_info(%s) Error: %s\n", hwname, snd_strerror(err)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     snd_ctl_close(ctlhandle); | 
					
						
							|  |  |  |     ctlhandle=0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!ctlhandle) { | 
					
						
							|  |  |  |     printf("No Echoaudio cards found, sorry.\n"); | 
					
						
							|  |  |  |     return(0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Reads available controls
 | 
					
						
							|  |  |  |   if (OpenControls(card, cardname)) | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mouseButton=0; | 
					
						
							|  |  |  |   Gang=0;		// Set the gang button off, because has annoying side effects during initialization
 | 
					
						
							|  |  |  |   Mainw_geom.st=NOPOS; | 
					
						
							|  |  |  |   PVw_geom.st=NOPOS; | 
					
						
							|  |  |  |   LVw_geom.st=NOPOS; | 
					
						
							|  |  |  |   VUw_geom.st=NOPOS; | 
					
						
							|  |  |  |   Mixerw_geom.st=NOPOS; | 
					
						
							|  |  |  |   Vmixerw_geom.st=NOPOS; | 
					
						
							|  |  |  |   VUwindow=GMwindow=0; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:51:57 +00:00
										 |  |  |   GMixerSection.Inputs=fdIn+2;	// The correct value is set by Digital_mode_activate()
 | 
					
						
							|  |  |  |   GMixerSection.Outputs=fdOut+2; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   GMixerSection.VmixerFirst=nIn; | 
					
						
							|  |  |  |   GMixerSection.VmixerLast=nIn+vmixerControl.vchannels-1; | 
					
						
							|  |  |  |   GMixerSection.LineOut=GMixerSection.VmixerLast+1; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   // Read current mixer setting.
 | 
					
						
							|  |  |  |   if (mixerId) | 
					
						
							|  |  |  |     ReadMixer(&mixerControl); | 
					
						
							|  |  |  |   if (vmixerId) | 
					
						
							|  |  |  |     ReadMixer(&vmixerControl); | 
					
						
							|  |  |  |   if (pcmoutId) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |     ReadControl(pcmoutControl.Gain, nPOut, pcmoutControl.id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   if (lineinId) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |     ReadControl(lineinControl.Gain, nIn, lineinControl.id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   if (lineoutId) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |     ReadControl(lineoutControl.Gain, nLOut, lineoutId, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   if (p4InId) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |     ReadNominalLevels(&NominalIn); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |   if (p4OutId) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |     ReadNominalLevels(&NominalOut); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   //@@ check the values
 | 
					
						
							|  |  |  |   if (load) { | 
					
						
							|  |  |  |     FILE *f; | 
					
						
							|  |  |  |     snprintf(str, 255, "%s/.Emixer_%s", getenv("HOME"), cardId); | 
					
						
							|  |  |  |     str[255]=0; | 
					
						
							|  |  |  |     if ((f=fopen(str, "r"))) { | 
					
						
							|  |  |  |       str[255]=0; | 
					
						
							|  |  |  |       while (fgets(str, 255, f)) { | 
					
						
							|  |  |  |         if (!strncmp("LineOut ", str, 8)) { | 
					
						
							|  |  |  |           sscanf(str+8, "%d %d", &o, &n); | 
					
						
							|  |  |  |           if (o>=0 && o<nLOut) | 
					
						
							|  |  |  |             lineoutControl.Gain[o]=n; | 
					
						
							|  |  |  |         } else if (!strncmp("LineIn ", str, 7)) { | 
					
						
							|  |  |  |           sscanf(str+7, "%d %d", &i, &n); | 
					
						
							|  |  |  |           if (i>=0 && i<nIn) | 
					
						
							|  |  |  |             lineinControl.Gain[i]=n; | 
					
						
							|  |  |  |         } else if (!strncmp("PcmOut ", str, 7)) { | 
					
						
							|  |  |  |           sscanf(str+7, "%d %d", &o, &n); | 
					
						
							|  |  |  |           if (o>=0 && o<nPOut) | 
					
						
							|  |  |  |             pcmoutControl.Gain[o]=n; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |         } else if (!strncmp("NominalOut ", str, 11)) { | 
					
						
							|  |  |  |           sscanf(str+11, "%d %d", &o, &n); | 
					
						
							|  |  |  |           if (o>=0 && o<fdOut) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |             NominalOut.Level[o]=!!n; | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |         } else if (!strncmp("NominalIn ", str, 10)) { | 
					
						
							|  |  |  |           sscanf(str+10, "%d %d", &i, &n); | 
					
						
							|  |  |  |           if (i>=0 && i<fdIn) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |             NominalIn.Level[i]=!!n; | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |         } else if (!strncmp("Mixer ", str, 6)) { | 
					
						
							|  |  |  |           sscanf(str+6, "%d %d %d", &o, &i, &n); | 
					
						
							|  |  |  |           if (o>=0 && o<nLOut && i>=0 && i<nIn) | 
					
						
							|  |  |  |             mixerControl.mixer[o][i].Gain=n; | 
					
						
							|  |  |  |         } else if (!strncmp("Vmixer ", str, 7)) { | 
					
						
							|  |  |  |           sscanf(str+7, "%d %d %d", &o, &i, &n); | 
					
						
							|  |  |  |           if (o>=0 && o<nLOut && i>=0 && i<nPOut) | 
					
						
							|  |  |  |             vmixerControl.mixer[o][i].Gain=n; | 
					
						
							|  |  |  |         } else if (!strncmp("MainWindow ", str, 11)) { | 
					
						
							|  |  |  |           sscanf(str+11, "%d %d %d %d", &Mainw_geom.x, &Mainw_geom.y, &Mainw_geom.w, &Mainw_geom.h); | 
					
						
							|  |  |  |         } else if (!strncmp("VUmetersWindow ", str, 15)) { | 
					
						
							|  |  |  |           sscanf(str+15, "%d %d %d", &VUw_geom.x, &VUw_geom.y, &VUw_geom.st); | 
					
						
							|  |  |  |         } else if (!strncmp("GfxMixerWindow ", str, 15)) { | 
					
						
							|  |  |  |           sscanf(str+15, "%d %d %d", &GMw_geom.x, &GMw_geom.y, &GMw_geom.st); | 
					
						
							|  |  |  |         } else if (!strncmp("PcmVolumeWindow ", str, 16)) { | 
					
						
							|  |  |  |           sscanf(str+16, "%d %d %d %d %d", &PVw_geom.x, &PVw_geom.y, &PVw_geom.w, &PVw_geom.h, &PVw_geom.st); | 
					
						
							|  |  |  |         } else if (!strncmp("LineVolumeWindow ", str, 17)) { | 
					
						
							|  |  |  |           sscanf(str+17, "%d %d %d %d %d", &LVw_geom.x, &LVw_geom.y, &LVw_geom.w, &LVw_geom.h, &LVw_geom.st); | 
					
						
							|  |  |  |         } else if (!strncmp("MixerWindow ", str, 12)) { | 
					
						
							|  |  |  |           sscanf(str+12, "%d %d %d %d %d", &Mixerw_geom.x, &Mixerw_geom.y, &Mixerw_geom.w, &Mixerw_geom.h, &Mixerw_geom.st); | 
					
						
							|  |  |  |         } else if (!strncmp("VmixerWindow ", str, 13)) { | 
					
						
							|  |  |  |           sscanf(str+13, "%d %d %d %d %d", &Vmixerw_geom.x, &Vmixerw_geom.y, &Vmixerw_geom.w, &Vmixerw_geom.h, &Vmixerw_geom.st); | 
					
						
							|  |  |  |         } else if (!strncmp("MiscControlsWindow ", str, 19)) { | 
					
						
							|  |  |  |           sscanf(str+19, "%d %d %d %d %d", &Miscw_geom.x, &Miscw_geom.y, &Miscw_geom.w, &Miscw_geom.h, &Miscw_geom.st); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   gtk_init(&argc, &argv); | 
					
						
							|  |  |  |   fnt=gdk_font_load("-misc-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"); | 
					
						
							|  |  |  |   if (!fnt) { | 
					
						
							|  |  |  |     printf("Cannot find the font\n"); | 
					
						
							|  |  |  |     exit(1); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Now assemble the control windows */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* ********** Misc controls window ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Miscwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |   sprintf(str, "%s Misc controls", cardId); | 
					
						
							|  |  |  |   gtk_window_set_title(GTK_WINDOW(Miscwindow), str); | 
					
						
							|  |  |  |   gtk_window_set_wmclass(GTK_WINDOW(Miscwindow), "misc", "Emixer"); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(Miscwindow), "delete_event", GTK_SIGNAL_FUNC(CloseWindow), (gpointer)&Miscw_geom); | 
					
						
							|  |  |  |   gtk_container_set_border_width(GTK_CONTAINER(Miscwindow), BORDER); | 
					
						
							|  |  |  |   if (Miscw_geom.st!=NOPOS) { | 
					
						
							|  |  |  |     gtk_widget_set_uposition(Miscwindow, Miscw_geom.x, Miscw_geom.y); | 
					
						
							|  |  |  |     gtk_window_set_default_size(GTK_WINDOW(Miscwindow), Miscw_geom.w, Miscw_geom.h); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mainbox=gtk_vbox_new(FALSE, SPACING); | 
					
						
							|  |  |  |   gtk_widget_show(mainbox); | 
					
						
							|  |  |  |   gtk_container_add(GTK_CONTAINER(Miscwindow), mainbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (p4InId) { | 
					
						
							|  |  |  |     // Consumer/professional analog input switches
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Input +4dBu"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, FALSE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<fdIn; i++) { | 
					
						
							|  |  |  |       sprintf(str, "%d", i); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |       button=NominalIn.Button[i]=gtk_toggle_button_new_with_label(str); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 1); | 
					
						
							|  |  |  |       gtk_widget_show(button); | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), NominalIn.Level[i]);	// Forces handler call
 | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(button), "toggled", GTK_SIGNAL_FUNC(Nominal_level_toggled), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), !NominalIn.Level[i]); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (p4OutId) { | 
					
						
							|  |  |  |     // Consumer/professional analog output switches
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Output +4dBu"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, FALSE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<fdOut; i++) { | 
					
						
							|  |  |  |       sprintf(str, "%d", i); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |       button=NominalOut.Button[i]=gtk_toggle_button_new_with_label(str); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 1); | 
					
						
							|  |  |  |       gtk_widget_show(button); | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), NominalOut.Level[i]); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(button), "toggled", GTK_SIGNAL_FUNC(Nominal_level_toggled), (gpointer)(long)(i+ECHO_MAXAUDIOINPUTS)); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), !NominalOut.Level[i]); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (dmodeId && ndmodes>1) { | 
					
						
							|  |  |  |     // Digital mode switch
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Digital mode"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, FALSE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dmodeOpt=gtk_option_menu_new(); | 
					
						
							|  |  |  |     gtk_widget_show(dmodeOpt); | 
					
						
							|  |  |  |     menu=gtk_menu_new(); | 
					
						
							|  |  |  |     gtk_widget_show(menu); | 
					
						
							|  |  |  |     for (i=0; i<ndmodes; i++) { | 
					
						
							|  |  |  |       menuitem=gtk_menu_item_new_with_label(dmodeName[i]); | 
					
						
							|  |  |  |       gtk_widget_show(menuitem); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(menuitem), "activate", Digital_mode_activate, (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       gtk_menu_append(GTK_MENU(menu), menuitem); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_option_menu_set_menu(GTK_OPTION_MENU(dmodeOpt), menu); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), dmodeOpt, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     gtk_option_menu_set_history(GTK_OPTION_MENU(dmodeOpt), dmodeVal=GetEnum(dmodeId)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (clocksrcId && nclocksrc>1) { | 
					
						
							|  |  |  |     // Clock source switch
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Clock source"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, FALSE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     clocksrcOpt=gtk_option_menu_new(); | 
					
						
							|  |  |  |     gtk_widget_show(clocksrcOpt); | 
					
						
							|  |  |  |     menu=gtk_menu_new(); | 
					
						
							|  |  |  |     gtk_widget_show(menu); | 
					
						
							|  |  |  |     for (i=0; i<nclocksrc; i++) { | 
					
						
							|  |  |  |       clocksrc_menuitem[i]=gtk_menu_item_new_with_label(clocksrcName[i]); | 
					
						
							|  |  |  |       gtk_widget_show(clocksrc_menuitem[i]); | 
					
						
							|  |  |  |       gtk_widget_set_sensitive(clocksrc_menuitem[i], FALSE); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(clocksrc_menuitem[i]), "activate", Clock_source_activate, (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       gtk_menu_append(GTK_MENU(menu), clocksrc_menuitem[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_option_menu_set_menu(GTK_OPTION_MENU(clocksrcOpt), menu); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), clocksrcOpt, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     gtk_option_menu_set_history(GTK_OPTION_MENU(clocksrcOpt), clocksrcVal=GetEnum(clocksrcId)); | 
					
						
							|  |  |  |     clocksrctimer=gtk_timeout_add(2000, CheckInputs, 0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (spdifmodeId && nspdifmodes>1) { | 
					
						
							|  |  |  |     // S/PDIF mode switch
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("S/PDIF mode"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, FALSE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spdifmodeOpt=gtk_option_menu_new(); | 
					
						
							|  |  |  |     gtk_widget_show(spdifmodeOpt); | 
					
						
							|  |  |  |     menu=gtk_menu_new(); | 
					
						
							|  |  |  |     gtk_widget_show(menu); | 
					
						
							|  |  |  |     for (i=0; i<nspdifmodes; i++) { | 
					
						
							|  |  |  |       menuitem=gtk_menu_item_new_with_label(spdifmodeName[i]); | 
					
						
							|  |  |  |       gtk_widget_show(menuitem); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(menuitem), "activate", SPDIF_mode_activate, (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       gtk_menu_append(GTK_MENU(menu), menuitem); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_option_menu_set_menu(GTK_OPTION_MENU(spdifmodeOpt), menu); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), spdifmodeOpt, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     gtk_option_menu_set_history(GTK_OPTION_MENU(spdifmodeOpt), spdifmodeVal=GetEnum(spdifmodeId)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:24:09 +00:00
										 |  |  |   // Switches
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  |   if (phantomId || clocksrcId) { | 
					
						
							| 
									
										
										
										
											2005-04-05 17:24:09 +00:00
										 |  |  |     frame=gtk_frame_new("Switches"); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2005-04-05 17:24:09 +00:00
										 |  |  |     hbox=gtk_vbox_new(FALSE, 0); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:24:09 +00:00
										 |  |  |     if (phantomId) { | 
					
						
							|  |  |  |       // Phantom power switch
 | 
					
						
							| 
									
										
										
										
											2005-04-05 17:28:24 +00:00
										 |  |  |       button=gtk_check_button_new_with_label("Phantom power"); | 
					
						
							|  |  |  |       gtk_widget_show(button); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0); | 
					
						
							|  |  |  |       ReadControl(&i, 1, PhantomPower.id, SND_CTL_ELEM_IFACE_MIXER); | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), i); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(button), "toggled", Switch_toggled, (gpointer)&PhantomPower); | 
					
						
							|  |  |  |       PhantomPower.Button=button; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (automuteId) { | 
					
						
							|  |  |  |       // Digital input automute switch
 | 
					
						
							|  |  |  |       button=gtk_check_button_new_with_label("Automute"); | 
					
						
							|  |  |  |       gtk_widget_show(button); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0); | 
					
						
							|  |  |  |       ReadControl(&i, 1, Automute.id, SND_CTL_ELEM_IFACE_CARD); | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), i); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(button), "toggled", Switch_toggled, (gpointer)&Automute); | 
					
						
							|  |  |  |       Automute.Button=button; | 
					
						
							| 
									
										
										
										
											2005-04-05 17:24:09 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2005-04-05 17:25:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Auto clock switch
 | 
					
						
							|  |  |  |     if (clocksrcId) { | 
					
						
							|  |  |  |       autoclockChkbutton=gtk_check_button_new_with_label("Autoclock"); | 
					
						
							|  |  |  |       gtk_widget_show(autoclockChkbutton); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(hbox), autoclockChkbutton, TRUE, FALSE, 0); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(autoclockChkbutton), "toggled", AutoClock_toggled, NULL); | 
					
						
							|  |  |  |       AutoClock=-1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ********** PCM volume window ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   pcmoutControl.window=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |   sprintf(str, "%s PCM volume", cardId); | 
					
						
							|  |  |  |   gtk_window_set_title(GTK_WINDOW (pcmoutControl.window), str); | 
					
						
							|  |  |  |   gtk_window_set_wmclass(GTK_WINDOW(pcmoutControl.window), "pcm", "Emixer"); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(pcmoutControl.window), "delete_event", GTK_SIGNAL_FUNC(CloseWindow), (gpointer)&PVw_geom); | 
					
						
							|  |  |  |   gtk_container_set_border_width(GTK_CONTAINER(pcmoutControl.window), BORDER); | 
					
						
							|  |  |  |   if (PVw_geom.st!=NOPOS) { | 
					
						
							|  |  |  |     gtk_widget_set_uposition(pcmoutControl.window, PVw_geom.x, PVw_geom.y); | 
					
						
							|  |  |  |     gtk_window_set_default_size(GTK_WINDOW(pcmoutControl.window), PVw_geom.w, PVw_geom.h); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mainbox=gtk_hbox_new(FALSE, SPACING); | 
					
						
							|  |  |  |   gtk_widget_show(mainbox); | 
					
						
							|  |  |  |   gtk_container_add(GTK_CONTAINER(pcmoutControl.window), mainbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pcmoutId) { | 
					
						
							|  |  |  |     // PCM Output volume widgets
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("PCM Output volume"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<nPOut; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       if (i<fdOut) | 
					
						
							|  |  |  |         sprintf(str, "A%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "D%d", i-fdOut); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |       value = INVERT(pcmoutControl.Gain[i]); | 
					
						
							|  |  |  |       pcmoutControl.adj[i]=gtk_adjustment_new(!value, ECHOGAIN_MINOUT, ECHOGAIN_MAXOUT, SHORTSTEP, LONGSTEP, 0); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       pcmoutControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(pcmoutControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(pcmoutControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), pcmoutControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(pcmoutControl.volume[i]), 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(pcmoutControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(PCM_volume_changed), (gpointer)(long)(i+ECHO_MAXAUDIOINPUTS)); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       // Value label
 | 
					
						
							|  |  |  |       pcmoutControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(pcmoutControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), pcmoutControl.label[i], FALSE, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |       gtk_adjustment_set_value(GTK_ADJUSTMENT(pcmoutControl.adj[i]), value); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(pcmoutControl.volume[0]), 0, 170);		// Set minimum y size
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ********** Line volume window ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   LVwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |   sprintf(str, "%s Line volume", cardId); | 
					
						
							|  |  |  |   gtk_window_set_title(GTK_WINDOW (LVwindow), str); | 
					
						
							|  |  |  |   gtk_window_set_wmclass(GTK_WINDOW(LVwindow), "line", "Emixer"); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(LVwindow), "delete_event", GTK_SIGNAL_FUNC(CloseWindow), (gpointer)&LVw_geom); | 
					
						
							|  |  |  |   gtk_container_set_border_width(GTK_CONTAINER(LVwindow), BORDER); | 
					
						
							|  |  |  |   if (LVw_geom.st!=NOPOS) { | 
					
						
							|  |  |  |     gtk_widget_set_uposition(LVwindow, LVw_geom.x, LVw_geom.y); | 
					
						
							|  |  |  |     gtk_window_set_default_size(GTK_WINDOW(LVwindow), LVw_geom.w, LVw_geom.h); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mainbox=gtk_hbox_new(FALSE, SPACING); | 
					
						
							|  |  |  |   gtk_widget_show(mainbox); | 
					
						
							|  |  |  |   gtk_container_add(GTK_CONTAINER(LVwindow), mainbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Line input volume widgets
 | 
					
						
							|  |  |  |   if (lineinId) { | 
					
						
							|  |  |  |     frame=gtk_frame_new("Analog input volume"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<fdIn; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       sprintf(str, "%d", i); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume (resolution is 0.5 dB)
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |       value = IN_INVERT(lineinControl.Gain[i]); | 
					
						
							|  |  |  |       lineinControl.adj[i]=gtk_adjustment_new(!value, ECHOGAIN_MININP, ECHOGAIN_MAXINP, SHORTSTEP, LONGSTEP*2, 0); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       lineinControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(lineinControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(lineinControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), lineinControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(lineinControl.volume[i]), 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(lineinControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(PCM_volume_changed), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       // Value label
 | 
					
						
							|  |  |  |       lineinControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(lineinControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), lineinControl.label[i], FALSE, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |       gtk_adjustment_set_value(GTK_ADJUSTMENT(lineinControl.adj[i]), value); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(lineinControl.volume[0]), 0, 170);	// Set minimum y size
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Line output volume widgets
 | 
					
						
							|  |  |  |   if (1) { | 
					
						
							|  |  |  |     frame=gtk_frame_new("Line output volume"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<nLOut; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       if (i<fdOut) | 
					
						
							|  |  |  |         sprintf(str, "A%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "D%d", i-fdOut); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume
 | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |       value = INVERT(lineoutControl.Gain[i]); | 
					
						
							|  |  |  |       lineoutControl.adj[i]=gtk_adjustment_new(!value, ECHOGAIN_MINOUT, ECHOGAIN_MAXOUT, SHORTSTEP, LONGSTEP, 0); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       lineoutControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(lineoutControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(lineoutControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), lineoutControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(lineoutControl.volume[i]), 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(lineoutControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(LineOut_volume_changed), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       // Value label
 | 
					
						
							|  |  |  |       lineoutControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(lineoutControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), lineoutControl.label[i], FALSE, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:50:30 +00:00
										 |  |  |       gtk_adjustment_set_value(GTK_ADJUSTMENT(lineoutControl.adj[i]), value); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(lineoutControl.volume[0]), 0, 170);		// Set minimum y size
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ********** Mixer window ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mixerId) { | 
					
						
							|  |  |  |     mixerControl.window=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |     sprintf(str, "%s Monitor mixer", cardId); | 
					
						
							|  |  |  |     gtk_window_set_title(GTK_WINDOW(mixerControl.window), str); | 
					
						
							|  |  |  |     gtk_window_set_wmclass(GTK_WINDOW(mixerControl.window), "mixer", "Emixer"); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(mixerControl.window), "delete_event", GTK_SIGNAL_FUNC(CloseWindow), (gpointer)&Mixerw_geom); | 
					
						
							|  |  |  |     gtk_container_set_border_width(GTK_CONTAINER(mixerControl.window), BORDER); | 
					
						
							|  |  |  |     if (Mixerw_geom.st!=NOPOS) { | 
					
						
							|  |  |  |       gtk_widget_set_uposition(mixerControl.window, Mixerw_geom.x, Mixerw_geom.y); | 
					
						
							|  |  |  |       gtk_window_set_default_size(GTK_WINDOW(mixerControl.window), Mixerw_geom.w, Mixerw_geom.h); | 
					
						
							|  |  |  | //      gdk_window_move_resize(mixerControl.window->window, Mixerw_geom.x, Mixerw_geom.y, Mixerw_geom.w, Mixerw_geom.h);
 | 
					
						
							|  |  |  | /*      gtk_widget_set_usize(mixerControl.window, Mixerw_geom.w, Mixerw_geom.h);
 | 
					
						
							|  |  |  |       gtk_widget_set_usize(mixerControl.window, -1, -1);*/ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mainbox=gtk_hbox_new(FALSE, SPACING); | 
					
						
							|  |  |  |     gtk_widget_show(mainbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(mixerControl.window), mainbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  |     // Mixer volume widgets
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Mixer input levels"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<nIn; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       if (i<fdIn) | 
					
						
							|  |  |  |         sprintf(str, "A%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "D%d", i-fdIn); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume
 | 
					
						
							|  |  |  |       mixerControl.adj[i]=gtk_adjustment_new(0, ECHOGAIN_MINOUT, ECHOGAIN_MAXOUT, SHORTSTEP, LONGSTEP, 0); | 
					
						
							|  |  |  |       mixerControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(mixerControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(mixerControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), mixerControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(mixerControl.volume[i]), 0); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(mixerControl.volume[i]), "grab_focus", GTK_SIGNAL_FUNC(Monitor_volume_clicked), (gpointer)i); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(mixerControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(Monitor_volume_changed), (gpointer)i); | 
					
						
							|  |  |  |       // Value label
 | 
					
						
							|  |  |  |       mixerControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(mixerControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), mixerControl.label[i], FALSE, FALSE, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(mixerControl.volume[0]), 0, 170);		// Set minimum y size
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Output channel selectors
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Mixer output"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     vbsel=gtk_vbox_new(FALSE, 2); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0); | 
					
						
							|  |  |  |     gtk_widget_show(vbsel); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), vbsel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bgroup=0; | 
					
						
							|  |  |  |     for (i=n=0; i<nLOut; i++) { | 
					
						
							|  |  |  |       if (i<fdOut) | 
					
						
							|  |  |  |         sprintf(str, "An-%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "Di-%d", i-fdOut); | 
					
						
							|  |  |  |       if (i) | 
					
						
							|  |  |  |         bgroup=gtk_radio_button_group(GTK_RADIO_BUTTON(mixerControl.outsel[i-1])); | 
					
						
							|  |  |  |       mixerControl.outsel[i]=gtk_radio_button_new_with_label(bgroup, str); | 
					
						
							|  |  |  |       gtk_widget_show(mixerControl.outsel[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbsel), mixerControl.outsel[i], FALSE, FALSE, 0); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(mixerControl.outsel[i]), "toggled", GTK_SIGNAL_FUNC(Mixer_Output_selector_clicked), (gpointer)i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mixerControl.input=0; | 
					
						
							|  |  |  |     mixerControl.output=-1; | 
					
						
							|  |  |  |     Mixer_Output_selector_clicked(0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else // REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Input channel selectors
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Mixer input"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0); | 
					
						
							|  |  |  |     vbsel=gtk_vbox_new(FALSE, 2); | 
					
						
							|  |  |  |     gtk_widget_show(vbsel); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), vbsel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bgroup=0; | 
					
						
							|  |  |  |     for (i=n=0; i<nIn; i++) { | 
					
						
							|  |  |  |       if (i<fdIn) | 
					
						
							|  |  |  |         sprintf(str, "An-%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "Di-%d", i-fdIn); | 
					
						
							|  |  |  |       if (i) | 
					
						
							|  |  |  |         bgroup=gtk_radio_button_group(GTK_RADIO_BUTTON(mixerControl.inpsel[i-1])); | 
					
						
							|  |  |  |       mixerControl.inpsel[i]=gtk_radio_button_new_with_label(bgroup, str); | 
					
						
							|  |  |  |       gtk_widget_show(mixerControl.inpsel[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbsel), mixerControl.inpsel[i], FALSE, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(mixerControl.inpsel[i]), "toggled", GTK_SIGNAL_FUNC(Mixer_Input_selector_clicked), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Mixer volume widgets
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Mixer output levels"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<nLOut; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       if (i<fdOut) | 
					
						
							|  |  |  |         sprintf(str, "A%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "D%d", i-fdOut); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume
 | 
					
						
							|  |  |  |       mixerControl.adj[i]=gtk_adjustment_new(0, ECHOGAIN_MINOUT, ECHOGAIN_MAXOUT, SHORTSTEP, LONGSTEP, 0); | 
					
						
							|  |  |  |       mixerControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(mixerControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(mixerControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), mixerControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(mixerControl.volume[i]), 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(mixerControl.volume[i]), "grab_focus", GTK_SIGNAL_FUNC(Monitor_volume_clicked), (gpointer)(long)i); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(mixerControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(Monitor_volume_changed), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       // Value label
 | 
					
						
							|  |  |  |       mixerControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(mixerControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), mixerControl.label[i], FALSE, FALSE, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(mixerControl.volume[0]), 0, 170);		// Set minimum y size
 | 
					
						
							|  |  |  |     mixerControl.input=-1; | 
					
						
							|  |  |  |     mixerControl.output=0; | 
					
						
							|  |  |  |     Mixer_Input_selector_clicked(0, 0); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ********** Vmixer window ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (vmixerId) { | 
					
						
							|  |  |  |     vmixerControl.window=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |     sprintf(str, "%s Vmixer", cardId); | 
					
						
							|  |  |  |     gtk_window_set_title(GTK_WINDOW(vmixerControl.window), str); | 
					
						
							|  |  |  |     gtk_window_set_wmclass(GTK_WINDOW(vmixerControl.window), "vmixer", "Emixer"); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(vmixerControl.window), "delete_event", GTK_SIGNAL_FUNC(CloseWindow), (gpointer)&Vmixerw_geom); | 
					
						
							|  |  |  |     gtk_container_set_border_width(GTK_CONTAINER(vmixerControl.window), BORDER); | 
					
						
							|  |  |  |     if (Vmixerw_geom.st!=NOPOS) { | 
					
						
							|  |  |  |       gtk_widget_set_uposition(vmixerControl.window, Vmixerw_geom.x, Vmixerw_geom.y); | 
					
						
							|  |  |  |       gtk_window_set_default_size(GTK_WINDOW(vmixerControl.window), Vmixerw_geom.w, Vmixerw_geom.h); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mainbox=gtk_hbox_new(FALSE, SPACING); | 
					
						
							|  |  |  |     gtk_widget_show(mainbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(vmixerControl.window), mainbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Vmixer volume widgets
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Vmixer vchannels levels"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<vmixerControl.vchannels; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       sprintf(str, "V%d", i); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume
 | 
					
						
							|  |  |  |       vmixerControl.adj[i]=gtk_adjustment_new(0, ECHOGAIN_MINOUT, ECHOGAIN_MAXOUT, SHORTSTEP, LONGSTEP, 0); | 
					
						
							|  |  |  |       vmixerControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(vmixerControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(vmixerControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), vmixerControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(vmixerControl.volume[i]), 0); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(vmixerControl.volume[i]), "grab_focus", GTK_SIGNAL_FUNC(Vmixer_volume_clicked), (gpointer)i); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(vmixerControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(Vmixer_volume_changed), (gpointer)i); | 
					
						
							|  |  |  |       // Value label
 | 
					
						
							|  |  |  |       vmixerControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(vmixerControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), vmixerControl.label[i], FALSE, FALSE, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(vmixerControl.volume[0]), 0, 170);		// Set minimum y size
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Input channel selectors
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Output"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0); | 
					
						
							|  |  |  |     vbsel=gtk_vbox_new(FALSE, 2); | 
					
						
							|  |  |  |     gtk_widget_show(vbsel); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), vbsel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bgroup=0; | 
					
						
							|  |  |  |     for (i=0; i<vmixerControl.outputs; i++) { | 
					
						
							|  |  |  |       if (i<fdOut) | 
					
						
							|  |  |  |         sprintf(str, "A%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "D%d", i); | 
					
						
							|  |  |  |       if (i) | 
					
						
							|  |  |  |         bgroup=gtk_radio_button_group(GTK_RADIO_BUTTON(vmixerControl.outsel[i-1])); | 
					
						
							|  |  |  |       vmixerControl.outsel[i]=gtk_radio_button_new_with_label(bgroup, str); | 
					
						
							|  |  |  |       gtk_widget_show(vmixerControl.outsel[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbsel), vmixerControl.outsel[i], FALSE, FALSE, 0); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(vmixerControl.outsel[i]), "toggled", GTK_SIGNAL_FUNC(Vmixer_output_selector_clicked), (gpointer)i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     vmixerControl.output=-1; | 
					
						
							|  |  |  |     Vmixer_output_selector_clicked(0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else // REVERSE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Input channel selectors
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Vchannel"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0); | 
					
						
							|  |  |  |     vbsel=gtk_vbox_new(FALSE, 2); | 
					
						
							|  |  |  |     gtk_widget_show(vbsel); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), vbsel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bgroup=0; | 
					
						
							|  |  |  |     for (i=0; i<vmixerControl.vchannels; i++) { | 
					
						
							|  |  |  |       sprintf(str, "V%d", i); | 
					
						
							|  |  |  |       if (i) | 
					
						
							|  |  |  |         bgroup=gtk_radio_button_group(GTK_RADIO_BUTTON(vmixerControl.vchsel[i-1])); | 
					
						
							|  |  |  |       vmixerControl.vchsel[i]=gtk_radio_button_new_with_label(bgroup, str); | 
					
						
							|  |  |  |       gtk_widget_show(vmixerControl.vchsel[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbsel), vmixerControl.vchsel[i], FALSE, FALSE, 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(vmixerControl.vchsel[i]), "toggled", GTK_SIGNAL_FUNC(Vmixer_vchannel_selector_clicked), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Vmixer volume widgets
 | 
					
						
							|  |  |  |     frame=gtk_frame_new("Vmixer output levels"); | 
					
						
							|  |  |  |     gtk_widget_show(frame); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(mainbox), frame, TRUE, TRUE, 0); | 
					
						
							|  |  |  |     hbox=gtk_hbox_new(TRUE, 1); | 
					
						
							|  |  |  |     gtk_widget_show(hbox); | 
					
						
							|  |  |  |     gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i=0; i<vmixerControl.outputs; i++) { | 
					
						
							|  |  |  |       vbox=gtk_vbox_new(FALSE, 0); | 
					
						
							|  |  |  |       gtk_widget_show(vbox); | 
					
						
							|  |  |  |       gtk_container_add(GTK_CONTAINER(hbox), vbox); | 
					
						
							|  |  |  |       // Channel label
 | 
					
						
							|  |  |  |       if (i<fdOut) | 
					
						
							|  |  |  |         sprintf(str, "A%d", i); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         sprintf(str, "D%d", i-fdOut); | 
					
						
							|  |  |  |       label=gtk_label_new(str); | 
					
						
							|  |  |  |       gtk_widget_show(label); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); | 
					
						
							|  |  |  |       // Volume
 | 
					
						
							|  |  |  |       vmixerControl.adj[i]=gtk_adjustment_new(0, ECHOGAIN_MINOUT, ECHOGAIN_MAXOUT, SHORTSTEP, LONGSTEP, 0); | 
					
						
							|  |  |  |       vmixerControl.volume[i]=gtk_vscale_new(GTK_ADJUSTMENT(vmixerControl.adj[i])); | 
					
						
							|  |  |  |       gtk_widget_show(vmixerControl.volume[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), vmixerControl.volume[i], TRUE, TRUE, 0); | 
					
						
							|  |  |  |       gtk_scale_set_draw_value(GTK_SCALE(vmixerControl.volume[i]), 0); | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |       gtk_signal_connect(GTK_OBJECT(vmixerControl.volume[i]), "grab_focus", GTK_SIGNAL_FUNC(Vmixer_volume_clicked), (gpointer)(long)i); | 
					
						
							|  |  |  |       gtk_signal_connect(GTK_OBJECT(vmixerControl.adj[i]), "value_changed", GTK_SIGNAL_FUNC(Vmixer_volume_changed), (gpointer)(long)i); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |       // Value label
 | 
					
						
							|  |  |  |       vmixerControl.label[i]=gtk_label_new("xxx"); | 
					
						
							|  |  |  |       gtk_widget_show(vmixerControl.label[i]); | 
					
						
							|  |  |  |       gtk_box_pack_start(GTK_BOX(vbox), vmixerControl.label[i], FALSE, FALSE, 0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     gtk_widget_set_usize(GTK_WIDGET(vmixerControl.volume[0]), 0, 170);		// Set minimum y size
 | 
					
						
							|  |  |  |     vmixerControl.vchannel=-1; | 
					
						
							|  |  |  |     Vmixer_vchannel_selector_clicked(0, 0); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ********** Main window ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Mainwindow=gtk_window_new(GTK_WINDOW_TOPLEVEL); | 
					
						
							|  |  |  |   sprintf(str, EM_VERSION, cardId); | 
					
						
							|  |  |  |   gtk_window_set_title(GTK_WINDOW(Mainwindow), str); | 
					
						
							|  |  |  |   gtk_window_set_wmclass(GTK_WINDOW(Mainwindow), "emixer", "Emixer"); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(Mainwindow), "delete_event", GTK_SIGNAL_FUNC(Mainwindow_delete), (gpointer)&Mainw_geom); | 
					
						
							|  |  |  |   gtk_container_set_border_width(GTK_CONTAINER(Mainwindow), BORDER); | 
					
						
							|  |  |  |   gtk_widget_show(Mainwindow); | 
					
						
							|  |  |  |   if (Mainw_geom.x!=NOPOS) { | 
					
						
							|  |  |  |     gtk_widget_set_uposition(Mainwindow, Mainw_geom.x, Mainw_geom.y); | 
					
						
							|  |  |  |     gtk_window_set_default_size(GTK_WINDOW(Mainwindow), Mainw_geom.w, Mainw_geom.h); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   mainbox=gtk_hbox_new(FALSE, SPACING); | 
					
						
							|  |  |  |   gtk_widget_show(mainbox); | 
					
						
							|  |  |  |   gtk_container_add(GTK_CONTAINER(Mainwindow), mainbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Gang button and its frame
 | 
					
						
							|  |  |  |   frame=gtk_frame_new("Gang"); | 
					
						
							|  |  |  |   gtk_widget_show(frame); | 
					
						
							|  |  |  |   gtk_box_pack_start(GTK_BOX(mainbox), frame, FALSE, FALSE, 0); | 
					
						
							|  |  |  |   hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |   gtk_widget_show(hbox); | 
					
						
							|  |  |  |   gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  |   button=gtk_toggle_button_new_with_label("On"); | 
					
						
							|  |  |  |   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); | 
					
						
							|  |  |  |   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), 1); | 
					
						
							|  |  |  |   gtk_widget_show(button); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(button), "toggled", Gang_button_toggled, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Controls frame
 | 
					
						
							|  |  |  |   frame=gtk_frame_new("Controls"); | 
					
						
							|  |  |  |   gtk_widget_show(frame); | 
					
						
							|  |  |  |   gtk_box_pack_end(GTK_BOX(mainbox), frame, FALSE, FALSE, 0); | 
					
						
							|  |  |  |   hbox=gtk_hbox_new(FALSE, 0); | 
					
						
							|  |  |  |   gtk_widget_show(hbox); | 
					
						
							|  |  |  |   gtk_container_add(GTK_CONTAINER(frame), hbox); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // VUmeters button
 | 
					
						
							|  |  |  |   if (vumetersId && vuswitchId) { | 
					
						
							|  |  |  |     button=gtk_toggle_button_new_with_label("VU"); | 
					
						
							|  |  |  |     gtk_widget_show(button); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(button), "toggled", VUmeters_button_click, 0); | 
					
						
							|  |  |  |     VUw_geom.toggler=button; | 
					
						
							|  |  |  |     if (VUw_geom.st==1) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Line volume button
 | 
					
						
							|  |  |  |   button=gtk_toggle_button_new_with_label("Line"); | 
					
						
							|  |  |  |   gtk_widget_show(button); | 
					
						
							|  |  |  |   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)LVwindow); | 
					
						
							|  |  |  |   LVw_geom.toggler=button; | 
					
						
							|  |  |  |   if (LVw_geom.st==1) | 
					
						
							|  |  |  |     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Misc controls button
 | 
					
						
							|  |  |  |   button=gtk_toggle_button_new_with_label("Misc"); | 
					
						
							|  |  |  |   gtk_widget_show(button); | 
					
						
							|  |  |  |   gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |   gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)Miscwindow); | 
					
						
							|  |  |  |   Miscw_geom.toggler=button; | 
					
						
							|  |  |  |   if (Miscw_geom.st==1) | 
					
						
							|  |  |  |     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mixerId) { | 
					
						
							|  |  |  |     // Graphical mixer button
 | 
					
						
							|  |  |  |     button=gtk_toggle_button_new_with_label("GrMix"); | 
					
						
							|  |  |  |     gtk_widget_show(button); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(button), "toggled", GMixer_button_click, 0); | 
					
						
							|  |  |  |     GMw_geom.toggler=button; | 
					
						
							|  |  |  |     if (GMw_geom.st==1) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Mixer button
 | 
					
						
							|  |  |  |     button=gtk_toggle_button_new_with_label("Mixer"); | 
					
						
							|  |  |  |     gtk_widget_show(button); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)mixerControl.window); | 
					
						
							|  |  |  |     Mixerw_geom.toggler=button; | 
					
						
							|  |  |  |     if (Mixerw_geom.st==1) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (vmixerId) { | 
					
						
							|  |  |  |     // Vmixer button
 | 
					
						
							|  |  |  |     button=gtk_toggle_button_new_with_label("Vmixer"); | 
					
						
							|  |  |  |     gtk_widget_show(button); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)vmixerControl.window); | 
					
						
							|  |  |  |     Vmixerw_geom.toggler=button; | 
					
						
							|  |  |  |     if (Vmixerw_geom.st==1) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (pcmoutId) { | 
					
						
							|  |  |  |     // PCM volume button
 | 
					
						
							|  |  |  |     button=gtk_toggle_button_new_with_label("PCM"); | 
					
						
							|  |  |  |     gtk_widget_show(button); | 
					
						
							|  |  |  |     gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 1); | 
					
						
							|  |  |  |     gtk_signal_connect(GTK_OBJECT(button), "toggled", ToggleWindow, (gpointer)pcmoutControl.window); | 
					
						
							|  |  |  |     PVw_geom.toggler=button; | 
					
						
							|  |  |  |     if (PVw_geom.st==1) | 
					
						
							|  |  |  |       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ********** GTK-main ********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Gang=1; | 
					
						
							|  |  |  |   if (dmodeId) | 
					
						
							| 
									
										
										
										
											2005-05-24 16:52:18 +00:00
										 |  |  |     Digital_mode_activate(dmodeOpt, (gpointer)(long)dmodeVal);	// Also calls SetSensitivity()
 | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |   gtk_widget_show(Mainwindow); | 
					
						
							|  |  |  |   gtk_main(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (save) { | 
					
						
							|  |  |  |     FILE *f; | 
					
						
							|  |  |  |     if (snprintf(str, 255, "%s/.Emixer_%s", getenv("HOME"), cardId)>0) { | 
					
						
							|  |  |  |       str[255]=0; | 
					
						
							|  |  |  |       if ((f=fopen(str, "w"))) { | 
					
						
							|  |  |  |         fprintf(f, "-- LineOut <channel> <gain>\n"); | 
					
						
							|  |  |  |         for (i=0; i<nLOut; i++) | 
					
						
							|  |  |  |           fprintf(f, "LineOut %2d %d\n", i, lineoutControl.Gain[i]); | 
					
						
							|  |  |  |         fprintf(f, "-- LineIn <channel> <gain>\n"); | 
					
						
							|  |  |  |         for (i=0; i<nIn; i++) | 
					
						
							|  |  |  |           fprintf(f, "LineIn %2d %d\n", i, lineinControl.Gain[i]); | 
					
						
							|  |  |  |         fprintf(f, "-- PcmOut <channel> <gain>\n"); | 
					
						
							|  |  |  |         for (i=0; i<nPOut; i++) | 
					
						
							|  |  |  |           fprintf(f, "PcmOut %2d %d\n", i, pcmoutControl.Gain[i]); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |         if (p4InId) { | 
					
						
							|  |  |  |           fprintf(f, "-- NominalIn <channel> <consumer level enabled>\n"); | 
					
						
							|  |  |  |           for (i=0; i<fdIn; i++) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |             fprintf(f, "NominalIn %2d %d\n", i, NominalIn.Level[i]); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (p4OutId) { | 
					
						
							|  |  |  |           fprintf(f, "-- NominalOut <channel> <consumer level enabled>\n"); | 
					
						
							|  |  |  |           for (o=0; o<fdOut; o++) | 
					
						
							| 
									
										
										
										
											2005-04-05 17:27:26 +00:00
										 |  |  |             fprintf(f, "NominalOut %2d %d\n", o, NominalOut.Level[o]); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         if (mixerId) { | 
					
						
							|  |  |  |           fprintf(f, "-- Mixer <output> <input> <gain>\n"); | 
					
						
							|  |  |  |           for (o=0; o<nLOut; o++) | 
					
						
							|  |  |  |             for (i=0; i<nIn; i++) | 
					
						
							|  |  |  |               fprintf(f, "Mixer %2d %2d %d\n", o, i, mixerControl.mixer[o][i].Gain); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (vmixerId) { | 
					
						
							|  |  |  |           fprintf(f, "-- Vmixer <output> <vchannel> <gain>\n"); | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |           for (o=0; o<nLOut; o++) | 
					
						
							|  |  |  |             for (i=0; i<nPOut; i++) | 
					
						
							|  |  |  |               fprintf(f, "Vmixer %2d %2d %d\n", o, i, vmixerControl.mixer[o][i].Gain); | 
					
						
							| 
									
										
										
										
											2005-01-19 10:48:45 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2004-12-29 13:02:53 +00:00
										 |  |  |         fprintf(f, "-- xxWindow <x> <y> <width> <height> <visible>\n"); | 
					
						
							|  |  |  |         fprintf(f, "MainWindow %d %d %d %d\n", Mainw_geom.x, Mainw_geom.y, Mainw_geom.w, Mainw_geom.h); | 
					
						
							|  |  |  |         if (VUwindow) | 
					
						
							|  |  |  |           gdk_window_get_root_origin(VUwindow->window, &VUw_geom.x, &VUw_geom.y); | 
					
						
							|  |  |  |         fprintf(f, "VUmetersWindow %d %d %d\n", VUw_geom.x, VUw_geom.y, VUw_geom.st); | 
					
						
							|  |  |  |         if (GMwindow) | 
					
						
							|  |  |  |           gdk_window_get_root_origin(GMwindow->window, &VUw_geom.x, &VUw_geom.y); | 
					
						
							|  |  |  |         fprintf(f, "GfxMixerWindow %d %d %d\n", GMw_geom.x, GMw_geom.y, GMw_geom.st); | 
					
						
							|  |  |  |         if (pcmoutId) { | 
					
						
							|  |  |  |           if (pcmoutControl.window->window) { | 
					
						
							|  |  |  |             gdk_window_get_root_origin(pcmoutControl.window->window, &PVw_geom.x, &PVw_geom.y); | 
					
						
							|  |  |  |             gdk_window_get_size(pcmoutControl.window->window, &PVw_geom.w, &PVw_geom.h); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           fprintf(f, "PcmVolumeWindow %d %d %d %d %d\n", PVw_geom.x, PVw_geom.y, PVw_geom.w, PVw_geom.h, !!GTK_WIDGET_VISIBLE(pcmoutControl.window)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (LVwindow->window) { | 
					
						
							|  |  |  |           gdk_window_get_root_origin(LVwindow->window, &LVw_geom.x, &LVw_geom.y); | 
					
						
							|  |  |  |           gdk_window_get_size(LVwindow->window, &LVw_geom.w, &LVw_geom.h); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         fprintf(f, "LineVolumeWindow %d %d %d %d %d\n", LVw_geom.x, LVw_geom.y, LVw_geom.w, LVw_geom.h, !!GTK_WIDGET_VISIBLE(LVwindow)); | 
					
						
							|  |  |  |         if (Miscwindow->window) { | 
					
						
							|  |  |  |           gdk_window_get_root_origin(Miscwindow->window, &Miscw_geom.x, &Miscw_geom.y); | 
					
						
							|  |  |  |           gdk_window_get_size(Miscwindow->window, &Miscw_geom.w, &Miscw_geom.h); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         fprintf(f, "MiscControlsWindow %d %d %d %d %d\n", Miscw_geom.x, Miscw_geom.y, Miscw_geom.w, Miscw_geom.h, !!GTK_WIDGET_VISIBLE(Miscwindow)); | 
					
						
							|  |  |  |         if (mixerId) { | 
					
						
							|  |  |  |           if (mixerControl.window->window) { | 
					
						
							|  |  |  |             gdk_window_get_root_origin(mixerControl.window->window, &Mixerw_geom.x, &Mixerw_geom.y); | 
					
						
							|  |  |  |             gdk_window_get_size(mixerControl.window->window, &Mixerw_geom.w, &Mixerw_geom.h); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           fprintf(f, "MixerWindow %d %d %d %d %d\n", Mixerw_geom.x, Mixerw_geom.y, Mixerw_geom.w, Mixerw_geom.h, !!GTK_WIDGET_VISIBLE(mixerControl.window)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (vmixerId) { | 
					
						
							|  |  |  |           if (vmixerControl.window->window) { | 
					
						
							|  |  |  |             gdk_window_get_root_origin(vmixerControl.window->window, &Vmixerw_geom.x, &Vmixerw_geom.y); | 
					
						
							|  |  |  |             gdk_window_get_size(vmixerControl.window->window, &Vmixerw_geom.w, &Vmixerw_geom.h); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           fprintf(f, "VmixerWindow %d %d %d %d %d\n", Vmixerw_geom.x, Vmixerw_geom.y, Vmixerw_geom.w, Vmixerw_geom.h, !!GTK_WIDGET_VISIBLE(vmixerControl.window)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         fprintf(f, "\n"); | 
					
						
							|  |  |  |         fclose(f); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (VUwindow) { | 
					
						
							|  |  |  |     SetVUmeters(0); | 
					
						
							|  |  |  |     gtk_timeout_remove(VUtimer); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (GMwindow) { | 
					
						
							|  |  |  |     SetVUmeters(0); | 
					
						
							|  |  |  |     gtk_timeout_remove(Mixtimer); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   snd_ctl_close(ctlhandle); | 
					
						
							|  |  |  |   return(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |