[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Patch] keys to tweak audio



Here is another patch. Nothing was changed except some parts of code are
protected with ``#if NAUDIO > 0'' making it possible to compile kernel
without audio support (Theo's remark).

cd /usr/src/sys && patch -p0 < audio_keys2.diff

PS: while editing dev/audio.c i found that there is nested ``if NAUDIO >
0'' and some functions are not protected with it. If it isn't done by
someone purposely i can clean it up.

-- 
Alexey V. Vatchenko
mailto: avv_(_at_)_mail_(_dot_)_zp_(_dot_)_ua
JID: avv_(_at_)_jabber_(_dot_)_zp_(_dot_)_ua
ICQ: 162799204
Index: dev/audio.c
===================================================================
RCS file: /cvs/src/sys/dev/audio.c,v
retrieving revision 1.46
diff -u -r1.46 audio.c
--- dev/audio.c	2 Jun 2005 19:04:18 -0000	1.46
+++ dev/audio.c	17 Mar 2006 13:26:21 -0000
@@ -213,6 +213,10 @@
 struct filterops audioread_filtops =
 	{ 1, NULL, filt_audiordetach, filt_audioread};
 
+/* Mixer manipulation using keyboard */
+static int wskbd_get_mixerdev(struct audio_softc *sc, int dir, int *index);
+int wskbd_set_mixervolume(int dir);
+
 int
 audioprobe(parent, match, aux)
 	struct device *parent;
@@ -3103,3 +3107,154 @@
 
 	return AUDIO_FILTWRITE(sc);
 }
+
+#if NAUDIO > 0
+static int
+wskbd_get_mixerdev(struct audio_softc *sc, int dir, int *index)
+{
+	mixer_devinfo_t mi;
+	int mixer_class;
+	int error;
+
+	/* looking for ``outputs'' */
+	for (mi.index = 0; ; mi.index++) {
+		error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
+		if (error != 0)
+			return (-1);
+
+		if (mi.type == AUDIO_MIXER_CLASS &&
+		    strcmp(mi.label.name, AudioCoutputs) == 0) {
+			mixer_class = mi.mixer_class;
+			break;
+		}
+	}
+
+	/* looking for ``outputs.master'' */
+	mi.index++;
+	for (;; mi.index++) {
+		error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
+		if (error != 0)
+			return (-1);
+
+		if (mi.type == AUDIO_MIXER_VALUE &&
+		    mi.mixer_class == mixer_class &&
+		    strcmp(mi.label.name, AudioNmaster) == 0) {
+			if (dir == 0) {
+				/* looking for ``outputs.master.mute'' */
+				if (mi.next < 0)
+					return (-1);
+
+				mi.index = mi.next;
+				error = sc->hw_if->query_devinfo(
+				    sc->hw_hdl, &mi);
+				if (error != 0)
+					return (-1);
+
+				if (mi.type != AUDIO_MIXER_ENUM ||
+				    strcmp(mi.label.name, AudioNmute) != 0)
+					return (-1);
+			}
+
+			*index = mi.index;
+			return 0;
+		}
+	}
+
+	return (-1);
+}
+
+int
+wskbd_set_mixervolume(int dir)
+{
+	struct audio_softc *sc;
+	mixer_devinfo_t mi;
+	mixer_ctrl_t ct;
+	int l, r;
+	int error;
+
+	if (audio_cd.cd_ndevs == 0 || (sc = *audio_cd.cd_devs) == NULL) {
+		DPRINTF(("wskbd_set_mixervolume: audio_cd\n"));
+		return (ENXIO);
+	}
+
+	error = wskbd_get_mixerdev(sc, dir, &ct.dev);
+	if (error == -1) {
+		DPRINTF(("wskbd_set_mixervolume: wskbd_get_mixerdev\n"));
+		return (ENXIO);
+	}
+
+	if (dir == 0) {
+		/*
+		 * Mute.
+		 * Use mixer_ioctl() for writing. It does many things for us.
+		 */
+		ct.type = AUDIO_MIXER_ENUM;
+		error = sc->hw_if->get_port(sc->hw_hdl, &ct);
+		if (error != 0) {
+			DPRINTF(("wskbd_set_mixervolume:"
+			    " get_port: %d\n", error));
+			return (error);
+		}
+
+		ct.un.ord ^= 1;	/* XXX - toggle */
+
+		error = mixer_ioctl(MIXER_DEVICE,
+		    AUDIO_MIXER_WRITE, (caddr_t)&ct, FWRITE, NULL);
+		if (error != 0) {
+			DPRINTF(("wskbd_set_mixervolume:"
+			    " mixer_ioctl: %d\n", error));
+			return (error);
+		}
+
+	} else {
+		mi.index = ct.dev;
+		error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
+		if (error != 0) {
+			DPRINTF(("wskbd_set_mixervolume:"
+			    " query_devinfo: %d\n", error));
+			return (error);
+		}
+
+		ct.type = AUDIO_MIXER_VALUE;
+
+		error = au_get_lr_value(sc, &ct, &l, &r);
+		if (error != 0) {
+			DPRINTF(("wskbd_set_mixervolume:"
+			    " au_get_lr_value: %d\n", error));
+			return (error);
+		}
+
+		if (dir > 0) {
+			/*
+			 * Raise volume
+			 */
+			if (l > (AUDIO_MAX_GAIN - mi.un.v.delta) ||
+			    r > (AUDIO_MAX_GAIN - mi.un.v.delta))
+				return (0);
+
+			l += mi.un.v.delta;
+			r += mi.un.v.delta;
+
+		} else {
+			/*
+			 * Lower volume
+			 */
+			if (l < (AUDIO_MIN_GAIN + mi.un.v.delta) ||
+			    r < (AUDIO_MIN_GAIN + mi.un.v.delta))
+				return (0);
+
+			l -= mi.un.v.delta;
+			r -= mi.un.v.delta;
+		}
+
+		error = au_set_lr_value(sc, &ct, l, r);
+		if (error != 0) {
+			DPRINTF(("wskbd_set_mixervolume:"
+			    " au_set_lr_value: %d\n", error));
+			return (error);
+		}
+	}
+
+	return (0);
+}
+#endif
Index: dev/pckbc/wskbdmap_mfii.c
===================================================================
RCS file: /cvs/src/sys/dev/pckbc/wskbdmap_mfii.c,v
retrieving revision 1.30
diff -u -r1.30 wskbdmap_mfii.c
--- dev/pckbc/wskbdmap_mfii.c	9 May 2005 05:08:57 -0000	1.30
+++ dev/pckbc/wskbdmap_mfii.c	17 Mar 2006 13:26:22 -0000
@@ -141,7 +141,10 @@
     KC(127),			KS_Pause, /* Break */
     KC(156),			KS_KP_Enter,
     KC(157), KS_Cmd1,		KS_Control_R,
+    KC(160),			KS_AudioMute,
     KC(170),			KS_Print_Screen,
+    KC(174),			KS_AudioLower,
+    KC(176),			KS_AudioRaise,
     KC(181),			KS_KP_Divide,
     KC(183),			KS_Print_Screen,
     KC(184), KS_Cmd2,		KS_Alt_R,	KS_Multi_key,
Index: dev/wscons/wskbd.c
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wskbd.c,v
retrieving revision 1.46
diff -u -r1.46 wskbd.c
--- dev/wscons/wskbd.c	14 Aug 2005 11:00:15 -0000	1.46
+++ dev/wscons/wskbd.c	17 Mar 2006 13:26:24 -0000
@@ -84,6 +84,8 @@
 #define	SCROLLBACK_SUPPORT
 #endif
 
+#include "audio.h"		/* NAUDIO (mixer tunning) */
+
 #include <sys/param.h>
 #include <sys/conf.h>
 #include <sys/device.h>
@@ -294,6 +296,10 @@
 
 void	wskbd_update_layout(struct wskbd_internal *, kbd_t);
 
+#if NAUDIO > 0
+int wskbd_set_mixervolume(int dir);
+#endif
+
 void
 wskbd_update_layout(struct wskbd_internal *id, kbd_t enc)
 {
@@ -1611,6 +1617,23 @@
 			ksym = group[gindex];
 		}
 	}
+
+#if NAUDIO > 0
+	/* Process Audio tunning keys */
+	switch (ksym) {
+	case KS_AudioMute:
+		(void) wskbd_set_mixervolume(0);
+		return (0);
+
+	case KS_AudioLower:
+		(void) wskbd_set_mixervolume(-1);
+		return (0);
+
+	case KS_AudioRaise:
+		(void) wskbd_set_mixervolume(1);
+		return (0);
+	}
+#endif
 
 	/* Process compose sequence and dead accents */
 	res = KS_voidSymbol;
Index: dev/wscons/wsksymdef.h
===================================================================
RCS file: /cvs/src/sys/dev/wscons/wsksymdef.h,v
retrieving revision 1.28
diff -u -r1.28 wsksymdef.h
--- dev/wscons/wsksymdef.h	15 May 2005 11:29:15 -0000	1.28
+++ dev/wscons/wsksymdef.h	17 Mar 2006 13:26:24 -0000
@@ -602,6 +602,10 @@
 #define KS_Pause		0xf3c1
 #define KS_Print_Screen		0xf3c2
 
+#define KS_AudioMute		0xf3d1
+#define KS_AudioLower		0xf3d2
+#define KS_AudioRaise		0xf3d3
+
 /*
  * Group 4 (command)
  */