r560 - trunk/src/target/OM-2007/applications/openmoko-dialer/src
tony_guan at sita.openmoko.org
tony_guan at sita.openmoko.org
Tue Jan 16 06:42:43 CET 2007
Author: tony_guan
Date: 2007-01-16 06:42:28 +0100 (Tue, 16 Jan 2007)
New Revision: 560
Added:
trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.c
trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.h
Log:
Volume control supported.
Added: trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.c
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.c 2007-01-16 05:41:33 UTC (rev 559)
+++ trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.c 2007-01-16 05:42:28 UTC (rev 560)
@@ -0,0 +1,208 @@
+/* ALSA.C -USED TO CONTROL VOLUME
+ * Copyright (C) 2007 Li Jiang
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+#include "alsa.h"
+#include <ctype.h>
+#include <glib.h>
+
+/* Set/Get volume */
+static snd_mixer_elem_t *pcm_element = NULL;
+static snd_mixer_t *mixer = NULL;
+
+static mixer_start = TRUE;;
+
+static guint mixer_timeout;
+
+/*
+ * mixer stuff
+ */
+static void
+parse_mixer_name(char *str, char **name, int *index)
+{
+ char *end;
+
+ while (isspace(*str))
+ str++;
+
+ if ((end = strchr(str, ',')) != NULL) {
+ *name = g_strndup(str, end - str);
+ end++;
+ *index = atoi(end);
+ }
+ else {
+ *name = g_strdup(str);
+ *index = 0;
+ }
+}
+
+int
+alsa_get_mixer(snd_mixer_t ** mixer, int card)
+{
+ char *dev;
+ int err;
+
+ g_debug("alsa_get_mixer");
+
+ dev = g_strdup_printf("hw:%i", card);
+
+ if ((err = snd_mixer_open(mixer, 0)) < 0) {
+ g_warning("alsa_get_mixer(): Failed to open empty mixer: %s",
+ snd_strerror(-err));
+ mixer = NULL;
+ return -1;
+ }
+ if ((err = snd_mixer_attach(*mixer, dev)) < 0) {
+ g_warning("alsa_get_mixer(): Attaching to mixer %s failed: %s",
+ dev, snd_strerror(-err));
+ return -1;
+ }
+ if ((err = snd_mixer_selem_register(*mixer, NULL, NULL)) < 0) {
+ g_warning("alsa_get_mixer(): Failed to register mixer: %s",
+ snd_strerror(-err));
+ return -1;
+ }
+ if ((err = snd_mixer_load(*mixer)) < 0) {
+ g_warning("alsa_get_mixer(): Failed to load mixer: %s",
+ snd_strerror(-err));
+ return -1;
+ }
+
+ g_free(dev);
+
+ return (*mixer != NULL);
+}
+
+
+static snd_mixer_elem_t* alsa_get_mixer_elem(snd_mixer_t *mixer, char *name, int index)
+{
+ snd_mixer_selem_id_t *selem_id;
+ snd_mixer_elem_t *elem;
+ snd_mixer_selem_id_alloca(&selem_id);
+
+ if (index != -1)
+ snd_mixer_selem_id_set_index(selem_id, index);
+ if (name != NULL)
+ snd_mixer_selem_id_set_name(selem_id, name);
+
+ elem = snd_mixer_find_selem(mixer, selem_id);
+
+ return elem;
+}
+
+static int
+alsa_setup_mixer(void)
+{
+ char *name;
+ long int a, b;
+ long alsa_min_vol, alsa_max_vol;
+ int err, index;
+
+ g_debug("alsa_setup_mixer");
+
+ if ((err = alsa_get_mixer(&mixer, 0)) < 0)
+ return err;
+
+ parse_mixer_name("Master", &name, &index);
+
+ pcm_element = alsa_get_mixer_elem(mixer, name, index);
+
+ g_free(name);
+
+ if (!pcm_element) {
+ g_warning("alsa_setup_mixer(): Failed to find mixer element: Master");
+ return -1;
+ }
+
+ /*
+ * Work around a bug in alsa-lib up to 1.0.0rc2 where the
+ * new range don't take effect until the volume is changed.
+ * This hack should be removed once we depend on Alsa 1.0.0.
+ */
+ snd_mixer_selem_get_playback_volume(pcm_element,
+ SND_MIXER_SCHN_FRONT_LEFT, &a);
+ snd_mixer_selem_get_playback_volume(pcm_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, &b);
+
+ snd_mixer_selem_get_playback_volume_range(pcm_element,
+ &alsa_min_vol, &alsa_max_vol);
+ snd_mixer_selem_set_playback_volume_range(pcm_element, 0, 100);
+
+ if (alsa_max_vol == 0) {
+ pcm_element = NULL;
+ return -1;
+ }
+
+ g_debug("alsa_setup_mixer: end");
+
+ return 0;
+}
+
+static int
+alsa_mixer_timeout(void *data)
+{
+ if (mixer) {
+ snd_mixer_close(mixer);
+ mixer = NULL;
+ pcm_element = NULL;
+ }
+ mixer_timeout = 0;
+ mixer_start = TRUE;
+
+ g_message("alsa mixer timed out");
+ return FALSE;
+}
+
+void
+alsa_get_volume(int *l, int *r)
+{
+ long ll = *l, lr = *r;
+
+ if (mixer_start) {
+ alsa_setup_mixer();
+ mixer_start = FALSE;
+ }
+
+ if (!pcm_element)
+ return;
+
+ snd_mixer_handle_events(mixer);
+
+ snd_mixer_selem_get_playback_volume(pcm_element,
+ SND_MIXER_SCHN_FRONT_LEFT, &ll);
+ snd_mixer_selem_get_playback_volume(pcm_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, &lr);
+ *l = ll;
+ *r = lr;
+
+ if (mixer_timeout)
+ gtk_timeout_remove(mixer_timeout);
+ mixer_timeout = gtk_timeout_add(5000, alsa_mixer_timeout, NULL);
+}
+
+
+void
+alsa_set_volume(int l, int r)
+{
+ if (!pcm_element)
+ return;
+
+ snd_mixer_selem_set_playback_volume(pcm_element,
+ SND_MIXER_SCHN_FRONT_LEFT, l);
+ snd_mixer_selem_set_playback_volume(pcm_element,
+ SND_MIXER_SCHN_FRONT_RIGHT, r);
+}
+
Added: trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.h
===================================================================
--- trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.h 2007-01-16 05:41:33 UTC (rev 559)
+++ trunk/src/target/OM-2007/applications/openmoko-dialer/src/alsa.h 2007-01-16 05:42:28 UTC (rev 560)
@@ -0,0 +1,36 @@
+/* ALSA.H -USED TO CONTROL VOLUME
+ * Copyright (C) 2007 Li Jiang
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+#ifndef ALSA_H
+#define ALSA_H
+
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+#include <alsa/asoundlib.h>
+#include <alsa/pcm_plugin.h>
+
+#include <gtk/gtk.h>
+
+#ifdef WORDS_BIGENDIAN
+# define IS_BIG_ENDIAN TRUE
+#else
+# define IS_BIG_ENDIAN FALSE
+#endif
+
+void alsa_get_volume(int *l, int *r);
+void alsa_set_volume(int l, int r);
+
+#endif
More information about the commitlog
mailing list