From 5f4d620716f4eacde5edf2e884d6616f604601041126ca7129320eff58c4dcdc Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Tue, 16 Oct 2007 15:43:52 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/alsa?expand=0&rev=21 --- alsa-lib-1.0.14a.tar.bz2 | 3 - alsa-lib-1.0.15.tar.bz2 | 3 + alsa-lib-fix-dmix-subdevice.diff | 34 - alsa-lib-fix-input-source-as-capture.diff | 77 - alsa-lib-fix-use-after-free.diff | 23 - alsa-lib-hg-fixes.diff | 3401 --------------------- alsa.changes | 6 + alsa.spec | 36 +- set_default_volume | 2 + 9 files changed, 24 insertions(+), 3561 deletions(-) delete mode 100644 alsa-lib-1.0.14a.tar.bz2 create mode 100644 alsa-lib-1.0.15.tar.bz2 delete mode 100644 alsa-lib-fix-dmix-subdevice.diff delete mode 100644 alsa-lib-fix-input-source-as-capture.diff delete mode 100644 alsa-lib-fix-use-after-free.diff delete mode 100644 alsa-lib-hg-fixes.diff diff --git a/alsa-lib-1.0.14a.tar.bz2 b/alsa-lib-1.0.14a.tar.bz2 deleted file mode 100644 index 7ab1200..0000000 --- a/alsa-lib-1.0.14a.tar.bz2 +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:de64de37a9acf918f347a3975e0ad3f58b24790dafdd03d9869a22ced4e5dcc7 -size 785668 diff --git a/alsa-lib-1.0.15.tar.bz2 b/alsa-lib-1.0.15.tar.bz2 new file mode 100644 index 0000000..c113347 --- /dev/null +++ b/alsa-lib-1.0.15.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f24272f3a32262c5285fc5bae0b9aa65494e8b22ac536313dbb60b8e4231e952 +size 793909 diff --git a/alsa-lib-fix-dmix-subdevice.diff b/alsa-lib-fix-dmix-subdevice.diff deleted file mode 100644 index ee4a0c7..0000000 --- a/alsa-lib-fix-dmix-subdevice.diff +++ /dev/null @@ -1,34 +0,0 @@ -tree 923dc1303d0a -parent 5e72b6913eb3 -author tiwai 1190034232 -7200 -committer tiwai 1190034232 -7200 -revision 2329 - -Fix subdevice number to 0 for dmix/dsnoop - -The dmix and dsnoop plugins need a fixed substream number instead of -the next-available one (-1) as the default number. Now it's set to 0. -diff --git a/src/conf/pcm/dmix.conf b/src/conf/pcm/dmix.conf ---- a/src/conf/pcm/dmix.conf -+++ b/src/conf/pcm/dmix.conf -@@ -20,7 +20,7 @@ pcm.!dmix { - } - @args.SUBDEV { - type integer -- default -1 -+ default 0 - } - @args.FORMAT { - type string -diff --git a/src/conf/pcm/dsnoop.conf b/src/conf/pcm/dsnoop.conf ---- a/src/conf/pcm/dsnoop.conf -+++ b/src/conf/pcm/dsnoop.conf -@@ -20,7 +20,7 @@ pcm.!dsnoop { - } - @args.SUBDEV { - type integer -- default -1 -+ default 0 - } - @args.FORMAT { - type string diff --git a/alsa-lib-fix-input-source-as-capture.diff b/alsa-lib-fix-input-source-as-capture.diff deleted file mode 100644 index 714b311..0000000 --- a/alsa-lib-fix-input-source-as-capture.diff +++ /dev/null @@ -1,77 +0,0 @@ -tree fc6b0b3b0c20 -parent 652611f58008 -author tiwai 1188391711 -7200 -committer tiwai 1188391711 -7200 -revision 2318 - -Handle "Input Source" as a capture element - -Some drivers use "Input Source" as the capture source mixer element because -mixer abstraction layer can't handle multiple "Capture Source" elements. -This patch adds a hack to handle Input Source as a capture route, and let -mixer apps know that it's a capture stuff, at least. -diff --git a/src/mixer/simple_none.c b/src/mixer/simple_none.c ---- a/src/mixer/simple_none.c -+++ b/src/mixer/simple_none.c -@@ -918,6 +918,19 @@ static int base_len(const char *name, se - } - p++; - } -+ -+ /* Special case - handle "Input Source" as a capture route. -+ * Note that it's *NO* capture source. A capture source is split over -+ * sub-elements, and multiple capture-sources will result in an error. -+ * That's why some drivers use "Input Source" as a workaround. -+ * Hence, this is a workaround for a workaround to get the things -+ * straight back again. Sigh. -+ */ -+ if (!strcmp(name, "Input Source")) { -+ *type = CTL_CAPTURE_ROUTE; -+ return strlen(name); -+ } -+ - return 0; - } - -@@ -1629,7 +1642,12 @@ static int simple_add1(snd_mixer_class_t - { - unsigned int n; - if (ctype == SND_CTL_ELEM_TYPE_ENUMERATED) { -- type = CTL_GLOBAL_ENUM; -+ if (type == CTL_PLAYBACK_ROUTE) -+ type = CTL_PLAYBACK_ENUM; -+ else if (type == CTL_CAPTURE_ROUTE) -+ type = CTL_CAPTURE_ENUM; -+ else -+ type = CTL_GLOBAL_ENUM; - break; - } - if (ctype != SND_CTL_ELEM_TYPE_BOOLEAN) -@@ -1644,7 +1662,12 @@ static int simple_add1(snd_mixer_class_t - case CTL_PLAYBACK_SWITCH: - case CTL_CAPTURE_SWITCH: - if (ctype == SND_CTL_ELEM_TYPE_ENUMERATED) { -- type = CTL_GLOBAL_ENUM; -+ if (type == CTL_PLAYBACK_SWITCH) -+ type = CTL_PLAYBACK_ENUM; -+ else if (type == CTL_CAPTURE_SWITCH) -+ type = CTL_CAPTURE_ENUM; -+ else -+ type = CTL_GLOBAL_ENUM; - break; - } - if (ctype != SND_CTL_ELEM_TYPE_BOOLEAN) -@@ -1654,7 +1677,12 @@ static int simple_add1(snd_mixer_class_t - case CTL_PLAYBACK_VOLUME: - case CTL_CAPTURE_VOLUME: - if (ctype == SND_CTL_ELEM_TYPE_ENUMERATED) { -- type = CTL_GLOBAL_ENUM; -+ if (type == CTL_PLAYBACK_VOLUME) -+ type = CTL_PLAYBACK_ENUM; -+ else if (type == CTL_CAPTURE_VOLUME) -+ type = CTL_CAPTURE_ENUM; -+ else -+ type = CTL_GLOBAL_ENUM; - break; - } - if (ctype != SND_CTL_ELEM_TYPE_INTEGER) diff --git a/alsa-lib-fix-use-after-free.diff b/alsa-lib-fix-use-after-free.diff deleted file mode 100644 index 3b55e68..0000000 --- a/alsa-lib-fix-use-after-free.diff +++ /dev/null @@ -1,23 +0,0 @@ -tree 65d47cdd771c -parent 7bb5b9fa6c6c -author tiwai 1187180553 -7200 -committer tiwai 1187180553 -7200 -revision 2312 - -Fix use after free - -Fixed use after free (ALSA bug#3300). -diff --git a/src/confmisc.c b/src/confmisc.c ---- a/src/confmisc.c -+++ b/src/confmisc.c -@@ -764,9 +764,9 @@ static int parse_card(snd_config_t *root - return err; - } - card = snd_card_get_index(str); -- free(str); - if (card < 0) - SNDERR("cannot find card '%s'", str); -+ free(str); - return card; - } - diff --git a/alsa-lib-hg-fixes.diff b/alsa-lib-hg-fixes.diff deleted file mode 100644 index 575f666..0000000 --- a/alsa-lib-hg-fixes.diff +++ /dev/null @@ -1,3401 +0,0 @@ -diff -r 9005d28a1f9e configure.in ---- a/configure.in Mon Jun 11 10:52:17 2007 +0200 -+++ b/configure.in Tue Aug 14 16:14:08 2007 +0200 -@@ -336,6 +336,23 @@ AC_ARG_ENABLE(alisp, - AC_ARG_ENABLE(alisp, - AS_HELP_STRING([--disable-alisp], [disable the alisp component]), - [build_alisp="$enableval"], [build_alisp="yes"]) -+AC_ARG_ENABLE(python, -+ AS_HELP_STRING([--disable-python], [disable the python components]), -+ [build_python="$enableval"], [build_python="yes"]) -+PYTHON_LIBS="" -+if test "$build_python" = "yes"; then -+ AC_ARG_WITH(pythonlibs, -+ AS_HELP_STRING([--with-pythonlibs=ldflags], -+ [specify python libraries (-lpthread -lm -ldl -lpython2.4)]), -+ pythonlibs="$withval", pythonlibs=`python-config --libs`) -+ if test -z "$pythonlibs" ; then -+ echo "Unable to determine python libraries! Probably python-config is not" -+ echo "available on this system. Please, use --with-pythonlibs options." -+ exit 1 -+ fi -+ PYTHON_LIBS="$pythonlibs" -+fi -+AC_SUBST(PYTHON_LIBS) - - if test "$build_seq" != "yes"; then - build_instr="no" -@@ -348,6 +365,7 @@ AM_CONDITIONAL(BUILD_SEQ, test x$build_s - AM_CONDITIONAL(BUILD_SEQ, test x$build_seq = xyes) - AM_CONDITIONAL(BUILD_INSTR, test x$build_instr = xyes) - AM_CONDITIONAL(BUILD_ALISP, test x$build_alisp = xyes) -+AM_CONDITIONAL(BUILD_PYTHON, test x$build_python = xyes) - - if test "$build_mixer" = "yes"; then - AC_DEFINE([BUILD_MIXER], "1", [Build mixer component]) -@@ -357,6 +375,9 @@ fi - fi - if test "$build_rawmidi" = "yes"; then - AC_DEFINE([BUILD_RAWMIDI], "1", [Build raw MIDI component]) -+fi -+if test "$build_hwdep" = "yes"; then -+ AC_DEFINE([BUILD_HWDEP], "1", [Build hwdep component]) - fi - if test "$build_seq" = "yes"; then - AC_DEFINE([BUILD_SEQ], "1", [Build sequencer component]) -@@ -376,7 +397,7 @@ pcm_plugins="" - pcm_plugins="" - fi - --PCM_PLUGIN_LIST="copy linear route mulaw alaw adpcm rate plug multi shm file null empty share meter hooks lfloat ladspa dmix dshare dsnoop asym iec958 softvol extplug ioplug" -+PCM_PLUGIN_LIST="copy linear route mulaw alaw adpcm rate plug multi shm file null empty share meter hooks lfloat ladspa dmix dshare dsnoop asym iec958 softvol extplug ioplug mmap_emul" - - build_pcm_plugin="no" - for t in $PCM_PLUGIN_LIST; do -@@ -414,7 +435,7 @@ if test "$HAVE_LIBPTHREAD" != "yes"; the - build_pcm_share="no" - fi - --if test "$softfloat" != "yes"; then -+if test "$softfloat" = "yes"; then - build_pcm_lfloat="no" - fi - -@@ -445,6 +466,7 @@ AM_CONDITIONAL(BUILD_PCM_PLUGIN_SOFTVOL, - AM_CONDITIONAL(BUILD_PCM_PLUGIN_SOFTVOL, test x$build_pcm_softvol = xyes) - AM_CONDITIONAL(BUILD_PCM_PLUGIN_EXTPLUG, test x$build_pcm_extplug = xyes) - AM_CONDITIONAL(BUILD_PCM_PLUGIN_IOPLUG, test x$build_pcm_ioplug = xyes) -+AM_CONDITIONAL(BUILD_PCM_PLUGIN_MMAP_EMUL, test x$build_pcm_mmap_emul = xyes) - - dnl Defines for plug plugin - if test "$build_pcm_rate" = "yes"; then -@@ -532,3 +554,21 @@ AC_OUTPUT(Makefile doc/Makefile doc/pict - modules/Makefile modules/mixer/Makefile modules/mixer/simple/Makefile \ - alsalisp/Makefile aserver/Makefile test/Makefile utils/Makefile \ - utils/alsa-lib.spec utils/alsa.pc) -+ -+dnl Create asoundlib.h dynamically according to configure options -+echo "Creating asoundlib.h..." -+cp "$srcdir"/include/asoundlib-head.h include/asoundlib.h -+test "$build_pcm" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_rawmidi" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_pcm" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_hwdep" = "yes" && echo "#include " >> include/asoundlib.h -+echo "#include " >> include/asoundlib.h -+test "$build_mixer" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_seq" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_instr" = "yes" && echo "#include " >> include/asoundlib.h -+test "$build_instr" = "yes" && echo "#include " >> include/asoundlib.h -+cat "$srcdir"/include/asoundlib-tail.h >> include/asoundlib.h -+ -diff -r 9005d28a1f9e doc/doxygen.cfg ---- a/doc/doxygen.cfg Mon Jun 11 10:52:17 2007 +0200 -+++ b/doc/doxygen.cfg Tue Aug 14 16:14:08 2007 +0200 -@@ -45,6 +45,7 @@ INPUT = index.doxygen \ - ../src/pcm/pcm_mmap.c \ - ../src/pcm/pcm_plugin.c \ - ../src/pcm/pcm_hw.c \ -+ ../src/pcm/pcm_mmap_emul.c \ - ../src/pcm/pcm_shm.c \ - ../src/pcm/pcm_null.c \ - ../src/pcm/pcm_copy.c \ -@@ -70,6 +71,7 @@ INPUT = index.doxygen \ - ../src/pcm/pcm_softvol.c \ - ../src/pcm/pcm_extplug.c \ - ../src/pcm/pcm_ioplug.c \ -+ ../src/pcm/pcm_empty.c \ - ../src/pcm/pcm_misc.c \ - ../src/pcm/pcm_simple.c \ - ../src/rawmidi \ -diff -r 9005d28a1f9e include/Makefile.am ---- a/include/Makefile.am Mon Jun 11 10:52:17 2007 +0200 -+++ b/include/Makefile.am Tue Aug 14 16:14:08 2007 +0200 -@@ -5,16 +5,59 @@ alsaincludedir = ${includedir}/alsa - - alsainclude_HEADERS = asoundlib.h asoundef.h \ - version.h global.h input.h output.h error.h \ -- conf.h pcm.h pcm_old.h pcm_plugin.h rawmidi.h timer.h \ -- hwdep.h control.h mixer.h mixer_abst.h \ -- seq_event.h seq.h seqmid.h seq_midi_event.h \ -- conv.h instr.h iatomic.h \ -- alisp.h pcm_external.h pcm_ioplug.h pcm_extplug.h \ -- pcm_rate.h control_external.h -+ conf.h control.h iatomic.h - --noinst_HEADERS = alsa sys.h search.h list.h aserver.h local.h alsa-symbols.h -+if BUILD_CTL_PLUGIN_EXT -+alsainclude_HEADERS += control_external.h -+endif - --CLEANFILES = stamp-vh version.h alsa -+if BUILD_PCM -+alsainclude_HEADERS += pcm.h pcm_old.h timer.h -+if BUILD_PCM_PLUGIN -+alsainclude_HEADERS += pcm_plugin.h -+endif -+if BUILD_PCM_PLUGIN_RATE -+alsainclude_HEADERS += pcm_rate.h -+endif -+if BUILD_PCM_PLUGIN_EXTPLUG -+alsainclude_HEADERS += pcm_external.h pcm_extplug.h -+endif -+if BUILD_PCM_PLUGIN_IOPLUG -+if !BUILD_PCM_PLUGIN_EXTPLUG -+alsainclude_HEADERS += pcm_external.h -+endif -+alsainclude_HEADERS += pcm_ioplug.h -+endif -+endif -+ -+if BUILD_RAWMIDI -+alsainclude_HEADERS += rawmidi.h -+endif -+ -+if BUILD_HWDEP -+alsainclude_HEADERS += hwdep.h -+endif -+ -+if BUILD_MIXER -+alsainclude_HEADERS += mixer.h mixer_abst.h -+endif -+ -+if BUILD_SEQ -+alsainclude_HEADERS += seq_event.h seq.h seqmid.h seq_midi_event.h -+endif -+ -+if BUILD_INSTR -+alsainclude_HEADERS += conv.h instr.h -+endif -+ -+if BUILD_ALISP -+alsainclude_HEADERS += alisp.h -+endif -+ -+noinst_HEADERS = alsa sys.h search.h list.h aserver.h local.h alsa-symbols.h \ -+ asoundlib-head.h asoundlib-tail.h -+ -+DISTCLEANFILES = stamp-vh version.h alsa asoundlib.h - - alsa: - ln -s $(top_srcdir)/include alsa -diff -r 9005d28a1f9e include/asoundlib-head.h ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/include/asoundlib-head.h Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,48 @@ -+/** -+ * \file include/asoundlib.h -+ * \brief Application interface library for the ALSA driver -+ * \author Jaroslav Kysela -+ * \author Abramo Bagnara -+ * \author Takashi Iwai -+ * \date 1998-2001 -+ * -+ * Application interface library for the ALSA driver -+ */ -+/* -+ * This library is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License as -+ * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#ifndef __ASOUNDLIB_H -+#define __ASOUNDLIB_H -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -diff -r 9005d28a1f9e include/asoundlib-tail.h ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/include/asoundlib-tail.h Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,2 @@ -+ -+#endif /* __ASOUNDLIB_H */ -diff -r 9005d28a1f9e include/asoundlib.h ---- a/include/asoundlib.h Mon Jun 11 10:52:17 2007 +0200 -+++ /dev/null Thu Jan 01 00:00:00 1970 +0000 -@@ -1,62 +0,0 @@ --/** -- * \file include/asoundlib.h -- * \brief Application interface library for the ALSA driver -- * \author Jaroslav Kysela -- * \author Abramo Bagnara -- * \author Takashi Iwai -- * \date 1998-2001 -- * -- * Application interface library for the ALSA driver -- */ --/* -- * This library is free software; you can redistribute it and/or modify -- * it under the terms of the GNU Lesser General Public License as -- * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General Public -- * License along with this library; if not, write to the Free Software -- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- * -- */ -- --#ifndef __ASOUNDLIB_H --#define __ASOUNDLIB_H -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#endif /* __ASOUNDLIB_H */ -diff -r 9005d28a1f9e include/pcm.h ---- a/include/pcm.h Mon Jun 11 10:52:17 2007 +0200 -+++ b/include/pcm.h Tue Aug 14 16:14:08 2007 +0200 -@@ -362,7 +362,9 @@ enum _snd_pcm_type { - SND_PCM_TYPE_IOPLUG, - /** External filter plugin */ - SND_PCM_TYPE_EXTPLUG, -- SND_PCM_TYPE_LAST = SND_PCM_TYPE_EXTPLUG -+ /** Mmap-emulation plugin */ -+ SND_PCM_TYPE_MMAP_EMUL, -+ SND_PCM_TYPE_LAST = SND_PCM_TYPE_MMAP_EMUL - }; - - /** PCM type */ -diff -r 9005d28a1f9e modules/mixer/simple/Makefile.am ---- a/modules/mixer/simple/Makefile.am Mon Jun 11 10:52:17 2007 +0200 -+++ b/modules/mixer/simple/Makefile.am Tue Aug 14 16:14:08 2007 +0200 -@@ -1,4 +1,5 @@ pkglibdir = @ALSA_PLUGIN_DIR@/smixer - pkglibdir = @ALSA_PLUGIN_DIR@/smixer -+pythonlibs = @PYTHON_LIBS@ - - AM_CFLAGS = -g -O2 -W -Wall - -@@ -7,6 +8,10 @@ pkglib_LTLIBRARIES = smixer-sbase.la \ - pkglib_LTLIBRARIES = smixer-sbase.la \ - smixer-ac97.la \ - smixer-hda.la -+ -+if BUILD_PYTHON -+pkglib_LTLIBRARIES += smixer-python.la -+endif - - noinst_HEADERS = sbase.h - -@@ -21,3 +26,9 @@ smixer_hda_la_SOURCES = hda.c sbasedl.c - smixer_hda_la_SOURCES = hda.c sbasedl.c - smixer_hda_la_LDFLAGS = -module -avoid-version - smixer_hda_la_LIBADD = ../../../src/libasound.la -+ -+if BUILD_PYTHON -+smixer_python_la_SOURCES = python.c -+smixer_python_la_LDFLAGS = -module -avoid-version $(pythonlibs) -+smixer_python_la_LIBADD = ../../../src/libasound.la -+endif -diff -r 9005d28a1f9e modules/mixer/simple/python.c ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/modules/mixer/simple/python.c Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,1002 @@ -+/* -+ * Mixer Interface - python binding simple abstact module -+ * Copyright (c) 2007 by Jaroslav Kysela -+ * -+ * -+ * This library is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License as -+ * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#include -+#include "config.h" -+#include "asoundlib.h" -+#include "mixer_abst.h" -+#include -+ -+struct python_priv { -+ int py_initialized; -+ PyObject *py_event_func; -+ PyObject *py_mdict; -+ PyObject *py_mixer; -+}; -+ -+#define SCRIPT ALSA_PLUGIN_DIR "/smixer/python/main.py" -+ -+struct pymelem { -+ PyObject_HEAD -+ sm_selem_t selem; -+ PyObject *py_mixer; -+ snd_mixer_elem_t *melem; -+}; -+ -+struct pymixer { -+ PyObject_HEAD -+ snd_mixer_class_t *class; -+ snd_mixer_t *mixer; -+ PyObject *mdict; -+ int hctl_count; -+ void **hctl; -+ int helem_count; -+ void **helem; -+ int melem_count; -+ void **melem; -+}; -+ -+static PyInterpreterState *main_interpreter; -+ -+static void *get_C_ptr(PyObject *obj, const char *attr) -+{ -+ PyObject *o; -+ -+ o = PyObject_GetAttr(obj, PyString_InternFromString(attr)); -+ if (!o) { -+ PyErr_Format(PyExc_TypeError, "missing '%s' attribute", attr); -+ return NULL; -+ } -+ if (!PyInt_Check(o)) { -+ PyErr_Format(PyExc_TypeError, "'%s' attribute is not integer", attr); -+ return NULL; -+ } -+ return (void *)PyInt_AsLong(o); -+} -+ -+static struct pymelem *melem_to_pymelem(snd_mixer_elem_t *elem) -+{ -+ return (struct pymelem *)((char *)snd_mixer_elem_get_private(elem) - offsetof(struct pymelem, selem)); -+} -+ -+static int pcall(struct pymelem *pymelem, const char *attr, PyObject *args, PyObject **_res) -+{ -+ PyObject *obj = (PyObject *)pymelem, *res; -+ int xres = 0; -+ -+ if (_res) -+ *_res = NULL; -+ obj = PyObject_GetAttr(obj, PyString_InternFromString(attr)); -+ if (!obj) { -+ PyErr_Format(PyExc_TypeError, "missing '%s' attribute", attr); -+ PyErr_Print(); -+ PyErr_Clear(); -+ Py_DECREF(args); -+ return -EIO; -+ } -+ res = PyObject_CallObject(obj, args); -+ Py_XDECREF(args); -+ if (res == NULL) { -+ PyErr_Print(); -+ PyErr_Clear(); -+ return -EIO; -+ } -+ if (_res && PyTuple_Check(res)) { -+ *_res = res; -+ res = PyTuple_GetItem(res, 0); -+ } -+ if (PyInt_Check(res)) { -+ xres = PyInt_AsLong(res); -+ } else if (res == Py_None) { -+ xres = 0; -+ } else if (PyBool_Check(res)) { -+ xres = res == Py_True; -+ } else { -+ PyErr_Format(PyExc_TypeError, "wrong result from '%s'!", attr); -+ PyErr_Print(); -+ PyErr_Clear(); -+ Py_DECREF(res); -+ if (_res) -+ *_res = NULL; -+ return -EIO; -+ } -+ if (_res && *_res) -+ return xres; -+ Py_DECREF(res); -+ return xres; -+} -+ -+static int is_ops(snd_mixer_elem_t *elem, int dir, int cmd, int val) -+{ -+ PyObject *obj1; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ char *s, fcn[32] = "opsIs"; -+ int res, xdir = 1, xval = 0; -+ -+ switch (cmd) { -+ case SM_OPS_IS_ACTIVE: s = "Active"; xdir = 0; break; -+ case SM_OPS_IS_MONO: s = "Mono"; break; -+ case SM_OPS_IS_CHANNEL: s = "Channel"; xval = 1; break; -+ case SM_OPS_IS_ENUMERATED: s = "Enumerated"; xdir = val == 1; break; -+ case SM_OPS_IS_ENUMCNT: s = "EnumCnt"; break; -+ default: -+ return 1; -+ } -+ strcat(fcn, s); -+ -+ obj1 = PyTuple_New(xdir + xval); -+ if (xdir) { -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ if (xval) -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(val)); -+ } -+ res = pcall(pymelem, fcn, obj1, NULL); -+ return res < 0 ? 0 : res; -+} -+ -+static int get_x_range_ops(snd_mixer_elem_t *elem, int dir, -+ long *min, long *max, const char *attr) -+{ -+ PyObject *obj1, *res; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ int err; -+ -+ obj1 = PyTuple_New(1); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ err = pcall(pymelem, attr, obj1, &res); -+ if (err >= 0) { -+ err = !PyInt_Check(PyTuple_GetItem(res, 1)) || !PyInt_Check(PyTuple_GetItem(res, 2)); -+ if (err) { -+ err = !PyLong_Check(PyTuple_GetItem(res, 1)) || !PyLong_Check(PyTuple_GetItem(res, 2)); -+ if (err) { -+ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); -+ PyErr_Print(); -+ PyErr_Clear(); -+ err = -EIO; -+ } else { -+ *min = PyLong_AsLong(PyTuple_GetItem(res, 1)); -+ *max = PyLong_AsLong(PyTuple_GetItem(res, 2)); -+ } -+ } else { -+ *min = PyInt_AsLong(PyTuple_GetItem(res, 1)); -+ *max = PyInt_AsLong(PyTuple_GetItem(res, 2)); -+ } -+ } -+ Py_XDECREF(res); -+ return err; -+} -+ -+static int get_range_ops(snd_mixer_elem_t *elem, int dir, -+ long *min, long *max) -+{ -+ return get_x_range_ops(elem, dir, min, max, "opsGetRange"); -+} -+ -+static int set_range_ops(snd_mixer_elem_t *elem, int dir, -+ long min, long max) -+{ -+ PyObject *obj1; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ -+ obj1 = PyTuple_New(3); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(min)); -+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(max)); -+ return pcall(pymelem, "opsGetRange", obj1, NULL); -+} -+ -+static int get_x_ops(snd_mixer_elem_t *elem, int dir, -+ snd_mixer_selem_channel_id_t channel, long *value, -+ const char *attr) -+{ -+ PyObject *obj1, *res; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ int err; -+ -+ obj1 = PyTuple_New(2); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(channel)); -+ err = pcall(pymelem, attr, obj1, &res); -+ if (err >= 0) { -+ err = !PyInt_Check(PyTuple_GetItem(res, 1)); -+ if (err) { -+ err = !PyLong_Check(PyTuple_GetItem(res, 1)); -+ if (err) { -+ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); -+ PyErr_Print(); -+ PyErr_Clear(); -+ err = -EIO; -+ } else { -+ *value = PyLong_AsLong(PyTuple_GetItem(res, 1)); -+ } -+ } else { -+ *value = PyInt_AsLong(PyTuple_GetItem(res, 1)); -+ } -+ } -+ Py_XDECREF(res); -+ return err; -+} -+ -+static int get_volume_ops(snd_mixer_elem_t *elem, int dir, -+ snd_mixer_selem_channel_id_t channel, long *value) -+{ -+ return get_x_ops(elem, dir, channel, value, "opsGetVolume"); -+} -+ -+static int get_switch_ops(snd_mixer_elem_t *elem, int dir, -+ snd_mixer_selem_channel_id_t channel, int *value) -+{ -+ long value1; -+ int res; -+ res = get_x_ops(elem, dir, channel, &value1, "opsGetSwitch"); -+ *value = value1; -+ return res; -+} -+ -+static int get_dB_ops(snd_mixer_elem_t *elem, -+ int dir, -+ snd_mixer_selem_channel_id_t channel, -+ long *value) -+{ -+ return get_x_ops(elem, dir, channel, value, "opsGetDB"); -+} -+ -+static int get_dB_range_ops(snd_mixer_elem_t *elem, int dir, -+ long *min, long *max) -+{ -+ return get_x_range_ops(elem, dir, min, max, "opsGetDBRange"); -+} -+ -+static int set_volume_ops(snd_mixer_elem_t *elem, int dir, -+ snd_mixer_selem_channel_id_t channel, long value) -+{ -+ PyObject *obj1; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ -+ obj1 = PyTuple_New(3); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(channel)); -+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(value)); -+ return pcall(pymelem, "opsSetVolume", obj1, NULL); -+} -+ -+ -+static int set_switch_ops(snd_mixer_elem_t *elem, int dir, -+ snd_mixer_selem_channel_id_t channel, int value) -+{ -+ PyObject *obj1; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ -+ obj1 = PyTuple_New(3); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(channel)); -+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(value)); -+ return pcall(pymelem, "opsSetSwitch", obj1, NULL); -+} -+ -+static int set_dB_ops(snd_mixer_elem_t *elem, int dir, -+ snd_mixer_selem_channel_id_t channel, -+ long db_gain, int xdir) -+{ -+ PyObject *obj1; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ -+ obj1 = PyTuple_New(4); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(dir)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(channel)); -+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(db_gain)); -+ PyTuple_SET_ITEM(obj1, 3, PyInt_FromLong(xdir)); -+ return pcall(pymelem, "opsSetDB", obj1, NULL); -+} -+ -+static int enum_item_name_ops(snd_mixer_elem_t *elem, -+ unsigned int item, -+ size_t maxlen, char *buf) -+{ -+ PyObject *obj1, *res; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ int err; -+ unsigned int len; -+ char *s; -+ -+ obj1 = PyTuple_New(1); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(item)); -+ err = pcall(pymelem, "opsGetEnumItemName", obj1, &res); -+ if (err >= 0) { -+ err = !PyString_Check(PyTuple_GetItem(res, 1)); -+ if (err) { -+ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); -+ PyErr_Print(); -+ PyErr_Clear(); -+ err = -EIO; -+ } else { -+ s = PyString_AsString(PyTuple_GetItem(res, 1)); -+ len = strlen(s); -+ if (maxlen - 1 > len) -+ len = maxlen - 1; -+ memcpy(buf, s, len); -+ buf[len] = '\0'; -+ } -+ } -+ Py_XDECREF(res); -+ return err; -+} -+ -+static int get_enum_item_ops(snd_mixer_elem_t *elem, -+ snd_mixer_selem_channel_id_t channel, -+ unsigned int *itemp) -+{ -+ PyObject *obj1, *res; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ int err; -+ -+ obj1 = PyTuple_New(1); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(channel)); -+ err = pcall(pymelem, "opsGetEnumItem", obj1, &res); -+ if (err >= 0) { -+ err = !PyInt_Check(PyTuple_GetItem(res, 1)); -+ if (err) { -+ PyErr_Format(PyExc_TypeError, "wrong result (invalid tuple)"); -+ PyErr_Print(); -+ PyErr_Clear(); -+ err = -EIO; -+ } else { -+ *itemp = PyInt_AsLong(PyTuple_GetItem(res, 1)); -+ } -+ } -+ Py_XDECREF(res); -+ return err; -+} -+ -+static int set_enum_item_ops(snd_mixer_elem_t *elem, -+ snd_mixer_selem_channel_id_t channel, -+ unsigned int item) -+{ -+ PyObject *obj1; -+ struct pymelem *pymelem = melem_to_pymelem(elem); -+ -+ obj1 = PyTuple_New(2); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong(channel)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong(item)); -+ return pcall(pymelem, "opsSetEnumItem", obj1, NULL); -+} -+ -+static struct sm_elem_ops simple_python_ops = { -+ .is = is_ops, -+ .get_range = get_range_ops, -+ .get_dB_range = get_dB_range_ops, -+ .set_range = set_range_ops, -+ .get_volume = get_volume_ops, -+ .get_dB = get_dB_ops, -+ .set_volume = set_volume_ops, -+ .set_dB = set_dB_ops, -+ .get_switch = get_switch_ops, -+ .set_switch = set_switch_ops, -+ .enum_item_name = enum_item_name_ops, -+ .get_enum_item = get_enum_item_ops, -+ .set_enum_item = set_enum_item_ops -+}; -+ -+static void selem_free(snd_mixer_elem_t *elem) -+{ -+ sm_selem_t *simple = snd_mixer_elem_get_private(elem); -+ -+ if (simple->id) { -+ snd_mixer_selem_id_free(simple->id); -+ simple->id = NULL; -+ } -+} -+ -+static PyObject * -+pymelem_cap(struct pymelem *pymelem ATTRIBUTE_UNUSED, void *priv) -+{ -+ return PyInt_FromLong((long)priv); -+} -+ -+static PyObject * -+pymelem_get_caps(struct pymelem *pymelem, void *priv ATTRIBUTE_UNUSED) -+{ -+ return PyInt_FromLong(pymelem->selem.caps); -+} -+ -+static PyObject * -+pymelem_get_name(struct pymelem *pymelem, void *priv ATTRIBUTE_UNUSED) -+{ -+ return PyString_FromString(snd_mixer_selem_id_get_name(pymelem->selem.id)); -+} -+ -+static PyObject * -+pymelem_get_index(struct pymelem *pymelem, void *priv ATTRIBUTE_UNUSED) -+{ -+ return PyInt_FromLong(snd_mixer_selem_id_get_index(pymelem->selem.id)); -+} -+ -+static int -+pymelem_set_caps(struct pymelem *pymelem, PyObject *val, void *priv ATTRIBUTE_UNUSED) -+{ -+ if (!PyInt_Check(val)) { -+ PyErr_SetString(PyExc_TypeError, "The last attribute value must be an integer"); -+ return -1; -+ } -+ pymelem->selem.caps = PyInt_AsLong(val); -+ return 0; -+} -+ -+static PyObject * -+pymelem_ignore(struct pymelem *pymelem ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) -+{ -+ Py_RETURN_NONE; -+} -+ -+static PyObject * -+pymelem_ignore1(struct pymelem *pymelem ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) -+{ -+ Py_RETURN_TRUE; -+} -+ -+static PyObject * -+pymelem_error(struct pymelem *pymelem ATTRIBUTE_UNUSED, PyObject *args ATTRIBUTE_UNUSED) -+{ -+ return PyInt_FromLong(-EIO); -+} -+ -+static PyObject * -+pymelem_attach(struct pymelem *pymelem, PyObject *args) -+{ -+ PyObject *obj; -+ snd_hctl_elem_t *helem; -+ int err; -+ -+ if (!PyArg_ParseTuple(args, "O", &obj)) -+ return NULL; -+ helem = (snd_hctl_elem_t *)get_C_ptr(obj, "get_C_helem"); -+ if (helem == NULL) -+ return NULL; -+ err = snd_mixer_elem_attach(pymelem->melem, helem); -+ if (err < 0) { -+ PyErr_Format(PyExc_RuntimeError, "Cannot attach hcontrol element to mixer element: %s", snd_strerror(err)); -+ return NULL; -+ } -+ Py_RETURN_NONE; -+} -+ -+static PyObject * -+pymelem_detach(struct pymelem *pymelem, PyObject *args) -+{ -+ PyObject *obj; -+ snd_hctl_elem_t *helem; -+ int err; -+ -+ if (!PyArg_ParseTuple(args, "O", &obj)) -+ return NULL; -+ helem = (snd_hctl_elem_t *)get_C_ptr(obj, "get_C_helem"); -+ if (helem == NULL) -+ return NULL; -+ err = snd_mixer_elem_detach(pymelem->melem, helem); -+ if (err < 0) { -+ PyErr_Format(PyExc_RuntimeError, "Cannot detach hcontrol element to mixer element: %s", snd_strerror(err)); -+ return NULL; -+ } -+ Py_RETURN_NONE; -+} -+ -+static PyObject * -+pymelem_event_info(struct pymelem *pymelem, PyObject *args) -+{ -+ if (!PyArg_ParseTuple(args, "")) -+ return NULL; -+ return PyInt_FromLong(snd_mixer_elem_info(pymelem->melem)); -+} -+ -+static PyObject * -+pymelem_event_value(struct pymelem *pymelem, PyObject *args) -+{ -+ if (!PyArg_ParseTuple(args, "")) -+ return NULL; -+ return PyInt_FromLong(snd_mixer_elem_value(pymelem->melem)); -+} -+ -+static int -+pymelem_init(struct pymelem *pymelem, PyObject *args, PyObject *kwds ATTRIBUTE_UNUSED) -+{ -+ char *name; -+ long index, weight; -+ snd_mixer_selem_id_t *id; -+ int err; -+ -+ if (!PyArg_ParseTuple(args, "Osii", &pymelem->py_mixer, &name, &index, &weight)) -+ return -1; -+ memset(&pymelem->selem, 0, sizeof(pymelem->selem)); -+ if (snd_mixer_selem_id_malloc(&id)) -+ return -1; -+ snd_mixer_selem_id_set_name(id, name); -+ snd_mixer_selem_id_set_index(id, index); -+ pymelem->selem.id = id; -+ pymelem->selem.ops = &simple_python_ops; -+ err = snd_mixer_elem_new(&pymelem->melem, SND_MIXER_ELEM_SIMPLE, -+ weight, &pymelem->selem, selem_free); -+ if (err < 0) { -+ snd_mixer_selem_id_free(id); -+ return -1; -+ } -+ return 0; -+} -+ -+static void -+pymelem_dealloc(struct pymelem *self) -+{ -+ selem_free(self->melem); -+ self->ob_type->tp_free(self); -+} -+ -+static PyGetSetDef pymelem_getseters[] = { -+ {"CAP_GVOLUME", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_GVOLUME}, -+ {"CAP_GSWITCH", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_GSWITCH}, -+ {"CAP_PVOLUME", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_PVOLUME}, -+ {"CAP_PVOLUME_JOIN", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_PVOLUME_JOIN}, -+ {"CAP_PSWITCH", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_PSWITCH}, -+ {"CAP_PSWITCH_JOIN", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_PSWITCH_JOIN}, -+ {"CAP_CVOLUME", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_CVOLUME}, -+ {"CAP_CVOLUME_JOIN", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_CVOLUME_JOIN}, -+ {"CAP_CSWITCH", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_CSWITCH}, -+ {"CAP_CSWITCH_JOIN", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_CSWITCH_JOIN}, -+ {"CAP_CSWITCH_EXCL", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_CSWITCH_EXCL}, -+ {"CAP_PENUM", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_PENUM}, -+ {"CAP_CENUM", (getter)pymelem_cap, NULL, NULL, (void *)SM_CAP_CENUM}, -+ -+ {"caps", (getter)pymelem_get_caps, (setter)pymelem_set_caps, NULL, NULL}, -+ -+ {"name", (getter)pymelem_get_name, NULL, NULL, NULL}, -+ {"index", (getter)pymelem_get_index, NULL, NULL, NULL}, -+ -+ {NULL,NULL,NULL,NULL,NULL} -+}; -+ -+static PyMethodDef pymelem_methods[] = { -+ {"attach", (PyCFunction)pymelem_attach, METH_VARARGS, NULL}, -+ {"detach", (PyCFunction)pymelem_detach, METH_VARARGS, NULL}, -+ -+ /* "default" functions - no functionality */ -+ {"opsIsActive", (PyCFunction)pymelem_ignore1, METH_VARARGS, NULL}, -+ {"opsIsMono", (PyCFunction)pymelem_ignore, METH_VARARGS, NULL}, -+ {"opsIsChannel", (PyCFunction)pymelem_ignore, METH_VARARGS, NULL}, -+ {"opsIsEnumerated", (PyCFunction)pymelem_ignore, METH_VARARGS, NULL}, -+ {"opsIsEnumCnt", (PyCFunction)pymelem_ignore, METH_VARARGS, NULL}, -+ -+ {"opsGetDB", (PyCFunction)pymelem_error, METH_VARARGS, NULL}, -+ -+ {"eventInfo", (PyCFunction)pymelem_event_info, METH_VARARGS, NULL}, -+ {"eventValue", (PyCFunction)pymelem_event_value, METH_VARARGS, NULL}, -+ -+ {NULL,NULL,0,NULL} -+}; -+ -+static PyTypeObject pymelem_type = { -+ PyObject_HEAD_INIT(0) -+ tp_name: "smixer_python.InternalMElement", -+ tp_basicsize: sizeof(struct pymelem), -+ tp_dealloc: (destructor)pymelem_dealloc, -+ tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, -+ tp_doc: NULL /* mixerinit__doc__ */, -+ tp_getset: pymelem_getseters, -+ tp_init: (initproc)pymelem_init, -+ tp_alloc: PyType_GenericAlloc, -+ tp_new: PyType_GenericNew, -+ tp_free: PyObject_Del, -+ tp_methods: pymelem_methods, -+}; -+ -+static PyObject * -+pymixer_attach_hctl(struct pymixer *pymixer, PyObject *args) -+{ -+ PyObject *obj; -+ snd_hctl_t *hctl; -+ void **hctls; -+ int err; -+ -+ if (!PyArg_ParseTuple(args, "O", &obj)) -+ return NULL; -+ hctl = (snd_hctl_t *)get_C_ptr(obj, "get_C_hctl"); -+ if (hctl == NULL) -+ return NULL; -+ err = snd_mixer_attach_hctl(pymixer->mixer, hctl); -+ if (err < 0) { -+ PyErr_Format(PyExc_RuntimeError, "Cannot attach hctl: %s", snd_strerror(err)); -+ return NULL; -+ } -+ hctls = realloc(pymixer->hctl, sizeof(void *) * (pymixer->hctl_count+1) * 2); -+ if (hctls == NULL) { -+ PyErr_SetString(PyExc_RuntimeError, "No enough memory"); -+ return NULL; -+ } -+ pymixer->hctl = hctls; -+ pymixer->hctl[pymixer->hctl_count*2] = (void *)hctl; -+ pymixer->hctl[pymixer->hctl_count*2+1] = (void *)obj; -+ pymixer->hctl_count++; -+ Py_INCREF(obj); -+ Py_RETURN_NONE; -+} -+ -+static PyObject * -+pymixer_register(struct pymixer *pymixer, PyObject *args) -+{ -+ int err; -+ -+ if (!PyArg_ParseTuple(args, "")) -+ return NULL; -+ err = snd_mixer_class_register(pymixer->class, pymixer->mixer); -+ if (err < 0) { -+ PyErr_Format(PyExc_RuntimeError, "Cannot register mixer: %s", snd_strerror(err)); -+ return NULL; -+ } -+ Py_RETURN_NONE; -+} -+ -+static PyObject * -+pymixer_melement_new(struct pymixer *pymixer, PyObject *args) -+{ -+ PyObject *obj, *obj1, *obj2; -+ char *class, *name; -+ long index, weight; -+ -+ if (!PyArg_ParseTuple(args, "ssii", &class, &name, &index, &weight)) -+ return NULL; -+ obj = PyDict_GetItemString(pymixer->mdict, class); -+ if (obj) { -+ obj1 = PyTuple_New(4); -+ if (PyTuple_SET_ITEM(obj1, 0, (PyObject *)pymixer)) -+ Py_INCREF((PyObject *)pymixer); -+ PyTuple_SET_ITEM(obj1, 1, PyString_FromString(name)); -+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong(index)); -+ PyTuple_SET_ITEM(obj1, 3, PyInt_FromLong(weight)); -+ obj2 = PyObject_CallObject(obj, obj1); -+ Py_XDECREF(obj1); -+ if (obj2) { -+ struct pymelem *pymelem = (struct pymelem *)obj2; -+ void **melems = realloc(pymixer->melem, sizeof(void *) * (pymixer->melem_count + 1) * 2); -+ if (melems == NULL) { -+ Py_DECREF(obj2); -+ return NULL; -+ } -+ melems[pymixer->melem_count*2] = pymelem->melem; -+ melems[pymixer->melem_count*2+1] = obj2; -+ Py_INCREF(obj2); -+ pymixer->melem = melems; -+ pymixer->melem_count++; -+ } -+ } else { -+ PyErr_Format(PyExc_RuntimeError, "Cannot find class '%s'", class); -+ return NULL; -+ } -+ return obj2; -+} -+ -+static PyObject * -+pymixer_melement_add(struct pymixer *pymixer, PyObject *args) -+{ -+ PyObject *obj; -+ struct pymelem *pymelem; -+ int err; -+ -+ if (!PyArg_ParseTuple(args, "O", &obj)) -+ return NULL; -+ pymelem = (struct pymelem *)obj; -+ err = snd_mixer_elem_add(pymelem->melem, pymixer->class); -+ if (err < 0) { -+ PyErr_Format(PyExc_RuntimeError, "Cannot add mixer element: %s", snd_strerror(err)); -+ return NULL; -+ } -+ Py_RETURN_NONE; -+} -+ -+static int -+pymixer_init(struct pymixer *pymixer, PyObject *args, PyObject *kwds ATTRIBUTE_UNUSED) -+{ -+ long class, mixer; -+ -+ if (!PyArg_ParseTuple(args, "iiO", &class, &mixer, &pymixer->mdict)) -+ return -1; -+ pymixer->class = (snd_mixer_class_t *)class; -+ pymixer->mixer = (snd_mixer_t *)mixer; -+ pymixer->hctl_count = 0; -+ pymixer->hctl = NULL; -+ pymixer->helem_count = 0; -+ pymixer->helem = NULL; -+ pymixer->melem_count = 0; -+ pymixer->melem = NULL; -+ return 0; -+} -+ -+static void -+pymixer_free(struct pymixer *self) -+{ -+ int idx; -+ -+ for (idx = 0; idx < self->hctl_count; idx++) { -+ snd_mixer_detach_hctl(self->mixer, self->hctl[idx*2]); -+ Py_DECREF((PyObject *)self->hctl[idx*2+1]); -+ } -+ if (self->hctl) -+ free(self->hctl); -+ self->hctl_count = 0; -+ self->hctl = NULL; -+ for (idx = 0; idx < self->helem_count; idx++) -+ Py_DECREF((PyObject *)self->helem[idx*2+1]); -+ if (self->helem) -+ free(self->helem); -+ self->helem_count = 0; -+ self->helem = NULL; -+ for (idx = 0; idx < self->melem_count; idx++) -+ Py_DECREF((PyObject *)self->melem[idx*2+1]); -+ if (self->melem) -+ free(self->melem); -+ self->melem_count = 0; -+ self->melem = NULL; -+} -+ -+static void -+pymixer_dealloc(struct pymixer *self) -+{ -+ pymixer_free(self); -+ self->ob_type->tp_free(self); -+} -+ -+static PyGetSetDef pymixer_getseters[] = { -+ {NULL,NULL,NULL,NULL,NULL} -+}; -+ -+static PyMethodDef pymixer_methods[] = { -+ {"attachHCtl", (PyCFunction)pymixer_attach_hctl, METH_VARARGS, NULL}, -+ {"register", (PyCFunction)pymixer_register, METH_VARARGS, NULL}, -+ {"newMElement", (PyCFunction)pymixer_melement_new, METH_VARARGS, NULL}, -+ {"addMElement", (PyCFunction)pymixer_melement_add, METH_VARARGS, NULL}, -+ {NULL,NULL,0,NULL} -+}; -+ -+static PyTypeObject pymixer_type = { -+ PyObject_HEAD_INIT(0) -+ tp_name: "smixer_python.InternalMixer", -+ tp_basicsize: sizeof(struct pymixer), -+ tp_dealloc: (destructor)pymixer_dealloc, -+ tp_flags: Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, -+ tp_doc: NULL /* mixerinit__doc__ */, -+ tp_getset: pymixer_getseters, -+ tp_init: (initproc)pymixer_init, -+ tp_alloc: PyType_GenericAlloc, -+ tp_new: PyType_GenericNew, -+ tp_free: PyObject_Del, -+ tp_methods: pymixer_methods, -+}; -+ -+static PyMethodDef python_methods[] = { -+ {NULL, NULL, 0, NULL} -+}; -+ -+static PyObject *new_helem(struct python_priv *priv, snd_hctl_elem_t *helem) -+{ -+ PyObject *obj, *py_hctl = NULL, *obj1, *obj2; -+ snd_hctl_t *hctl = snd_hctl_elem_get_hctl(helem); -+ struct pymixer *pymixer = (struct pymixer *)priv->py_mixer; -+ int idx; -+ -+ for (idx = 0; idx < pymixer->hctl_count; idx++) { -+ if (pymixer->hctl[idx] == hctl) { -+ py_hctl = pymixer->hctl[idx*2+1]; -+ break; -+ } -+ } -+ if (py_hctl == NULL) -+ return NULL; -+ obj = PyDict_GetItemString(priv->py_mdict, "HElement"); -+ if (obj) { -+ obj1 = PyTuple_New(3); -+ if (PyTuple_SET_ITEM(obj1, 0, py_hctl)) -+ Py_INCREF(py_hctl); -+ PyTuple_SET_ITEM(obj1, 1, PyFloat_FromDouble(1)); -+ PyTuple_SET_ITEM(obj1, 2, PyInt_FromLong((long)helem)); -+ obj2 = PyObject_CallObject(obj, obj1); -+ if (obj2 == NULL) { -+ PyErr_Print(); -+ PyErr_Clear(); -+ } -+ Py_XDECREF(obj1); -+ } else { -+ SNDERR("Unable to create InternalMixer object"); -+ return NULL; -+ } -+ if (obj2) { -+ struct pymixer *pymixer = (struct pymixer *)priv->py_mixer; -+ void **helems = realloc(pymixer->helem, sizeof(void *) * (pymixer->helem_count + 1) * 2); -+ if (helems == NULL) { -+ Py_DECREF(obj2); -+ return NULL; -+ } -+ helems[pymixer->helem_count*2] = helem; -+ helems[pymixer->helem_count*2+1] = obj2; -+ Py_INCREF(obj2); -+ pymixer->helem = helems; -+ pymixer->helem_count++; -+ } -+ return obj2; -+} -+ -+static PyObject *find_helem(struct python_priv *priv, snd_hctl_elem_t *helem) -+{ -+ struct pymixer *pymixer = (struct pymixer *)priv->py_mixer; -+ int idx; -+ -+ for (idx = 0; idx < pymixer->helem_count; idx++) { -+ if (pymixer->helem[idx*2] == helem) -+ return (PyObject *)pymixer->helem[idx*2+1]; -+ } -+ return NULL; -+} -+ -+static PyObject *find_melem(struct python_priv *priv, snd_mixer_elem_t *melem) -+{ -+ struct pymixer *pymixer = (struct pymixer *)priv->py_mixer; -+ int idx; -+ -+ for (idx = 0; idx < pymixer->melem_count; idx++) { -+ if (pymixer->melem[idx*2] == melem) -+ return (PyObject *)pymixer->melem[idx*2+1]; -+ } -+ return NULL; -+} -+ -+int alsa_mixer_simple_event(snd_mixer_class_t *class, unsigned int mask, -+ snd_hctl_elem_t *helem, snd_mixer_elem_t *melem) -+{ -+ struct python_priv *priv = snd_mixer_sbasic_get_private(class); -+ PyThreadState *tstate, *origstate; -+ PyObject *t, *o, *r; -+ int res = -ENOMEM; -+ -+ tstate = PyThreadState_New(main_interpreter); -+ origstate = PyThreadState_Swap(tstate); -+ -+ t = PyTuple_New(3); -+ if (t) { -+ PyTuple_SET_ITEM(t, 0, (PyObject *)PyInt_FromLong(mask)); -+ o = find_helem(priv, helem); -+ if (mask & SND_CTL_EVENT_MASK_ADD) { -+ if (o == NULL) -+ o = new_helem(priv, helem); -+ } -+ if (o == NULL) -+ return 0; -+ if (PyTuple_SET_ITEM(t, 1, o)) -+ Py_INCREF(o); -+ o = melem ? find_melem(priv, melem) : Py_None; -+ if (PyTuple_SET_ITEM(t, 2, o)) -+ Py_INCREF(o); -+ r = PyObject_CallObject(priv->py_event_func, t); -+ Py_DECREF(t); -+ if (r) { -+ if (PyInt_Check(r)) { -+ res = PyInt_AsLong(r); -+ } else if (r == Py_None) { -+ res = 0; -+ } -+ Py_DECREF(r); -+ } else { -+ PyErr_Print(); -+ PyErr_Clear(); -+ res = -EIO; -+ } -+ } -+ -+ return res; -+} -+ -+static void alsa_mixer_simple_free(snd_mixer_class_t *class) -+{ -+ struct python_priv *priv = snd_mixer_sbasic_get_private(class); -+ -+ if (priv->py_mixer) { -+ pymixer_free((struct pymixer *)priv->py_mixer); -+ Py_DECREF(priv->py_mixer); -+ } -+ if (priv->py_initialized) { -+ Py_XDECREF(priv->py_event_func); -+ Py_Finalize(); -+ } -+ free(priv); -+} -+ -+int alsa_mixer_simple_finit(snd_mixer_class_t *class, -+ snd_mixer_t *mixer, -+ const char *device) -+{ -+ struct python_priv *priv; -+ FILE *fp; -+ const char *file; -+ PyObject *obj, *obj1, *obj2, *py_mod, *mdict; -+ -+ priv = calloc(1, sizeof(*priv)); -+ if (priv == NULL) -+ return -ENOMEM; -+ -+ snd_mixer_sbasic_set_private(class, priv); -+ snd_mixer_sbasic_set_private_free(class, alsa_mixer_simple_free); -+ -+ file = getenv("ALSA_MIXER_SIMPLE_MPYTHON"); -+ if (file == NULL) -+ file = SCRIPT; -+ -+ fp = fopen(file, "r"); -+ if (fp == NULL) { -+ SNDERR("Unable to find python module '%s'", file); -+ return -ENODEV; -+ } -+ -+ Py_Initialize(); -+ if (PyType_Ready(&pymelem_type) < 0) -+ return -EIO; -+ if (PyType_Ready(&pymixer_type) < 0) -+ return -EIO; -+ Py_InitModule("smixer_python", python_methods); -+ priv->py_initialized = 1; -+ main_interpreter = PyThreadState_Get()->interp; -+ obj = PyImport_GetModuleDict(); -+ py_mod = PyDict_GetItemString(obj, "__main__"); -+ if (py_mod) { -+ mdict = priv->py_mdict = PyModule_GetDict(py_mod); -+ obj = PyString_FromString(file); -+ if (obj) -+ PyDict_SetItemString(mdict, "__file__", obj); -+ Py_XDECREF(obj); -+ obj = PyString_FromString(device); -+ if (obj) -+ PyDict_SetItemString(mdict, "device", obj); -+ Py_XDECREF(obj); -+ Py_INCREF(&pymixer_type); -+ PyModule_AddObject(py_mod, "InternalMElement", (PyObject *)&pymelem_type); -+ PyModule_AddObject(py_mod, "InternalMixer", (PyObject *)&pymixer_type); -+ obj = PyDict_GetItemString(mdict, "InternalMixer"); -+ if (obj) { -+ obj1 = PyTuple_New(3); -+ PyTuple_SET_ITEM(obj1, 0, PyInt_FromLong((long)class)); -+ PyTuple_SET_ITEM(obj1, 1, PyInt_FromLong((long)mixer)); -+ if (PyTuple_SET_ITEM(obj1, 2, mdict)) -+ Py_INCREF(mdict); -+ obj2 = PyObject_CallObject(obj, obj1); -+ Py_XDECREF(obj1); -+ PyDict_SetItemString(mdict, "mixer", obj2); -+ priv->py_mixer = obj2; -+ } else { -+ SNDERR("Unable to create InternalMixer object"); -+ return -EIO; -+ } -+ -+ -+ obj = PyRun_FileEx(fp, file, Py_file_input, mdict, mdict, 1); -+ if (obj == NULL) -+ PyErr_Print(); -+ Py_XDECREF(obj); -+ priv->py_event_func = PyDict_GetItemString(mdict, "event"); -+ if (priv->py_event_func == NULL) { -+ SNDERR("Unable to find python function 'event'"); -+ return -EIO; -+ } -+ } -+ return 0; -+} -diff -r 9005d28a1f9e modules/mixer/simple/python/common.py ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/modules/mixer/simple/python/common.py Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,228 @@ -+#!/usr/bin/python -+# -*- coding: utf-8 -*- -+# -*- Python -*- -+ -+from pyalsa.alsahcontrol import HControl, Element as HElement, \ -+ Info as HInfo, Value as HValue, InterfaceId, \ -+ EventMask, EventMaskRemove -+ -+MIXER = InterfaceId['Mixer'] -+MIXERS = str(MIXER) -+ -+class BaseElement(InternalMElement): -+ -+ def __init__(self, mixer, name, index, weight): -+ InternalMElement.__init__(self, mixer, name, index, weight) -+ self.channels = 0 -+ self.min = [0, 0] -+ self.max = [0, 0] -+ -+ def opsIsChannel(self, dir, chn): -+ return chn >= 0 and chn < self.channels -+ -+ def opsGetRange(self, dir): -+ return (0, self.min[dir], self.max[dir]) -+ -+ def opsSetRange(self, dir, min, max): -+ self.min[dir] = min -+ self.max[dir] = max -+ -+ def volumeToUser(self, info, dir, value): -+ min = info.min -+ max = info.max -+ if min == max: -+ return self.min[dir] -+ n = (value - min) * (self.max[dir] - self.min[dir]) -+ return self.min[dir] + (n + (max - min) / 2) / (max - min) -+ -+ def volumeFromUser(self, info, dir, value): -+ min = info.min -+ max = info.max -+ if self.max[dir] == self.min[dir]: -+ return min -+ n = (value - self.min[dir]) * (max - min) -+ return min + (n + (self.max[dir] - self.min[dir]) / 2) / (self.max[dir] - self.min[dir]) -+ -+class StandardElement(BaseElement): -+ -+ def __init__(self, mixer, name, index, weight): -+ BaseElement.__init__(self, mixer, name, index, weight) -+ self.channels = 1 -+ self.volume = [None, None] -+ self.volumeinfo = [None, None] -+ self.volumetuple = [None, None] -+ self.switch = [None, None] -+ self.switchinfo = [None, None] -+ self.switchtuple = [None, None] -+ -+ def decideChannels(self): -+ max = 0 -+ for i in [0, 1]: -+ if self.volume[i]: -+ count = self.volumeinfo[i].count -+ if count > max: -+ max = count -+ if self.switch[i]: -+ count = self.switchinfo[i].count -+ if count > max: -+ max = count -+ self.channels = max -+ -+ def attachVolume(self, helem, dir): -+ self.volume[dir] = helem -+ self.volumeinfo[dir] = HInfo(helem) -+ self.min[dir] = self.volumeinfo[dir].min -+ self.max[dir] = self.volumeinfo[dir].max -+ self.volumetuple[dir] = HValue(helem).getTuple(self.volumeinfo[dir].type, self.volumeinfo[dir].count) -+ -+ def attachSwitch(self, helem, dir): -+ self.switch[dir] = helem -+ self.switchinfo[dir] = HInfo(helem) -+ self.switchtuple[dir] = HValue(helem).getTuple(self.switchinfo[dir].type, self.switchinfo[dir].count) -+ -+ def attach(self, helem): -+ BaseElement.attach(self, helem) -+ if helem.name.endswith('Playback Volume'): -+ self.attachVolume(helem, 0) -+ self.caps |= self.CAP_PVOLUME -+ elif helem.name.endswith('Capture Volume'): -+ self.attachVolume(helem, 1) -+ self.caps |= self.CAP_CVOLUME -+ elif helem.name.endswith('Playback Switch'): -+ self.attachSwitch(helem, 0) -+ self.caps |= self.CAP_PSWITCH -+ elif helem.name.endswith('Capture Switch'): -+ self.attachSwitch(helem, 1) -+ self.caps |= self.CAP_CSWITCH -+ self.decideChannels() -+ self.eventInfo() -+ -+ def opsGetVolume(self, dir, chn): -+ return (0, self.volumeToUser(self.volumeinfo[dir], dir, self.volumetuple[dir][chn])) -+ -+ def opsSetVolume(self, dir, chn, value): -+ val = self.volumeFromUser(self.volumeinfo[dir], dir, value) -+ if self.volumetuple[dir][chn] == val: -+ return -+ a = list(self.volumetuple[dir]) -+ a[chn] = val -+ self.volumetuple[dir] = tuple(a) -+ hv = HValue(self.volume) -+ hv.setTuple(self.volumeinfo[dir].type, self.volumetuple[dir]) -+ hv.write() -+ -+ def opsGetSwitch(self, dir, chn): -+ return (0, self.switchtuple[dir][chn]) -+ -+ def opsSetSwitch(self, dir, chn, value): -+ if self.switchtuple[dir][chn] and value: -+ return -+ if not self.switchtuple[dir][chn] and not value: -+ return -+ a = list(self.switchtuple[dir]) -+ a[chn] = int(value) -+ self.switchtuple[dir] = tuple(a) -+ hv = HValue(self.switch[dir]) -+ hv.setTuple(self.switchinfo[dir].type, self.switchtuple[dir]) -+ hv.write() -+ -+ def update(self, helem): -+ for i in [0, 1]: -+ if helem == self.volume[i]: -+ self.volumetuple[i] = HValue(helem).getTuple(self.volumeinfo[i].type, self.volumeinfo[i].count) -+ elif helem == self.switch[i]: -+ self.switchtuple[i] = HValue(helem).getTuple(self.switchinfo[i].type, self.switchinfo[i].count) -+ self.eventValue() -+ -+class EnumElement(BaseElement): -+ -+ def __init__(self, mixer, name, index, weight): -+ BaseElement.__init__(self, mixer, name, index, weight) -+ self.mycaps = 0 -+ -+ def attach(self, helem): -+ BaseElement.attach(self, helem) -+ self.enum = helem -+ self.enuminfo = HInfo(helem) -+ self.enumtuple = HValue(helem).getTuple(self.enuminfo.type, self.enuminfo.count) -+ self.channels = self.enuminfo.count -+ self.texts = self.enuminfo.itemNames -+ self.caps |= self.mycaps -+ -+ def opsIsEnumerated(self, dir=-1): -+ if dir < 0: -+ return 1 -+ if dir == 0 and self.mycaps & self.CAP_PENUM: -+ return 1 -+ if dir == 1 and self.mycaps & self.CAP_CENUM: -+ return 1 -+ -+ def opsIsEnumCnt(self, dir): -+ return self.enuminfo.items -+ -+ def opsGetEnumItemName(self, item): -+ return (0, self.texts[item]) -+ -+ def opsGetEnumItem(self, chn): -+ if chn >= self.channels: -+ return -1 -+ return (0, self.enumtuple[chn]) -+ -+ def opsSetEnumItem(self, chn, value): -+ if chn >= self.channels: -+ return -1 -+ if self.enumtuple[chn] == value: -+ return -+ a = list(self.enumtuple) -+ a[chn] = int(value) -+ self.enumtuple = tuple(a) -+ hv = HValue(self.enum) -+ hv.setTuple(self.enuminfo.type, self.enumtuple) -+ hv.write() -+ -+ def update(self, helem): -+ self.enumtuple = HValue(helem).getTuple(self.enuminfo.type, self.enuminfo.count) -+ self.eventValue() -+ -+class EnumElementPlayback(EnumElement): -+ -+ def __init__(self, mixer, name, index, weight): -+ EnumElement.__init__(self, mixer, name, index, weight) -+ self.mycaps = self.CAP_PENUM -+ -+class EnumElementCapture(EnumElement): -+ -+ def __init__(self, mixer, name, index, weight): -+ EnumElement.__init__(self, mixer, name, index, weight) -+ self.mycaps = self.CAP_CENUM -+ -+ELEMS = [] -+ -+def element_add(helem): -+ key = helem.name+'//'+str(helem.index)+'//'+str(helem.interface) -+ if not CONTROLS.has_key(key): -+ return -+ val = CONTROLS[key] -+ felem = None -+ for elem in ELEMS: -+ if elem.name == val[0] and elem.index == val[1]: -+ felem = elem -+ break -+ if not felem: -+ felem = mixer.newMElement(val[3], val[0], val[1], val[2]) -+ mixer.addMElement(felem) -+ ELEMS.append(felem) -+ felem.attach(helem) -+ -+def eventHandler(evmask, helem, melem): -+ if evmask == EventMaskRemove: -+ return -+ if evmask & EventMask['Add']: -+ element_add(helem) -+ if evmask & EventMask['Value']: -+ melem.update(helem) -+ -+def init(): -+ hctl = HControl(device, load=False) -+ mixer.attachHCtl(hctl) -+ mixer.register() -diff -r 9005d28a1f9e modules/mixer/simple/python/hda.py ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/modules/mixer/simple/python/hda.py Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,42 @@ -+#!/usr/bin/python -+# -*- coding: utf-8 -*- -+# -*- Python -*- -+ -+alsacode('common') -+ -+CONTROLS = { -+'Headphone Playback Switch//0//'+MIXERS:["Headphone", 0, 1, "StandardElement"], -+'IEC958 Playback Switch//0//'+MIXERS:["IEC958", 0, 2, "StandardElement"], -+'Front Playback Volume//0//'+MIXERS:["Front", 0, 3, "StandardElement"], -+'Front Playback Switch//0//'+MIXERS:["Front", 0, 3, "StandardElement"], -+'Surround Playback Volume//0//'+MIXERS:["Surround", 0, 4, "StandardElement"], -+'Surround Playback Switch//0//'+MIXERS:["Surround", 0, 4, "StandardElement"], -+'Center Playback Volume//0//'+MIXERS:["Center", 0, 5, "StandardElement"], -+'Center Playback Switch//0//'+MIXERS:["Center", 0, 5, "StandardElement"], -+'LFE Playback Volume//0//'+MIXERS:["LFE", 0, 6, "StandardElement"], -+'LFE Playback Switch//0//'+MIXERS:["LFE", 0, 6, "StandardElement"], -+'Line Playback Volume//0//'+MIXERS:["Line", 0, 7, "StandardElement"], -+'Line Playback Switch//0//'+MIXERS:["Line", 0, 7, "StandardElement"], -+'CD Playback Volume//0//'+MIXERS:["CD", 0, 8, "StandardElement"], -+'CD Playback Switch//0//'+MIXERS:["CD", 0, 8, "StandardElement"], -+'Mic Playback Volume//0//'+MIXERS:["Mic", 0, 9, "StandardElement"], -+'Mic Playback Switch//0//'+MIXERS:["Mic", 0, 9, "StandardElement"], -+'PC Speaker Playback Volume//0//'+MIXERS:["PC Speaker", 0, 10, "StandardElement"], -+'PC Speaker Playback Switch//0//'+MIXERS:["PC Speaker", 0, 10, "StandardElement"], -+'Front Mic Playback Volume//0//'+MIXERS:["Front Mic", 0, 11, "StandardElement"], -+'Front Mic Playback Switch//0//'+MIXERS:["Front Mic", 0, 11, "StandardElement"], -+'Capture Switch//0//'+MIXERS:["Capture", 0, 12, "StandardElement"], -+'Capture Volume//0//'+MIXERS:["Capture", 0, 12, "StandardElement"], -+'Capture Switch//1//'+MIXERS:["Capture", 1, 13, "StandardElement"], -+'Capture Volume//1//'+MIXERS:["Capture", 1, 13, "StandardElement"], -+'Capture Switch//2//'+MIXERS:["Capture", 2, 14, "StandardElement"], -+'Capture Volume//2//'+MIXERS:["Capture", 2, 14, "StandardElement"], -+'Input Source//0//'+MIXERS:["Input Source", 0, 15, "EnumElementCapture"], -+'Input Source//1//'+MIXERS:["Input Source", 1, 16, "EnumElementCapture"], -+'Input Source//2//'+MIXERS:["Input Source", 2, 17, "EnumElementCapture"], -+} -+ -+def event(evmask, helem, melem): -+ return eventHandler(evmask, helem, melem) -+ -+init() -diff -r 9005d28a1f9e modules/mixer/simple/python/main.py ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/modules/mixer/simple/python/main.py Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,24 @@ -+#!/usr/bin/python -+# -*- coding: utf-8 -*- -+# -*- Python -*- -+ -+from os.path import dirname -+from pyalsa.alsacontrol import Control -+from sys import path -+path.insert(0, dirname(__file__)) -+ -+def alsacode(module): -+ execfile(dirname(__file__)+'/'+module+'.py', globals()) -+ -+ctl = Control(device) -+info = ctl.cardInfo() -+#mixername = info['mixername'] -+components = info['components'] -+del ctl -+ -+if components.find('HDA:') >= 0: -+ module = 'hda' -+else: -+ raise ValueError, "Mixer for this hardware is not implemented in python" -+ -+alsacode(module) -diff -r 9005d28a1f9e src/conf/cards/Makefile.am ---- a/src/conf/cards/Makefile.am Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/conf/cards/Makefile.am Tue Aug 14 16:14:08 2007 +0200 -@@ -35,6 +35,7 @@ cfg_files = aliases.conf \ - PC-Speaker.conf \ - PMac.conf \ - PMacToonie.conf \ -+ PS3.conf \ - RME9636.conf \ - RME9652.conf \ - SI7018.conf \ -diff -r 9005d28a1f9e src/conf/cards/PMac.conf ---- a/src/conf/cards/PMac.conf Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/conf/cards/PMac.conf Tue Aug 14 16:14:08 2007 +0200 -@@ -24,14 +24,14 @@ PMac.pcm.default { - type plug - slave.pcm { - @func concat -- strings [ "dmix:CARD=" $CARD ",FORMAT=S16" ] -+ strings [ "dmix:CARD=" $CARD ",FORMAT=S16_BE" ] - } - } - capture.pcm { - type plug - slave.pcm { - @func concat -- strings [ "dsnoop:CARD=" $CARD ",FORMAT=S16" ] -+ strings [ "dsnoop:CARD=" $CARD ",FORMAT=S16_BE" ] - } - } - } -diff -r 9005d28a1f9e src/conf/cards/PMacToonie.conf ---- a/src/conf/cards/PMacToonie.conf Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/conf/cards/PMacToonie.conf Tue Aug 14 16:14:08 2007 +0200 -@@ -33,7 +33,7 @@ PMacToonie.pcm.default { - type softvol - slave.pcm { - @func concat -- strings [ "dmix:CARD=" $CARD ",FORMAT=S16" ] -+ strings [ "dmix:CARD=" $CARD ",FORMAT=S16_BE" ] - } - control { - name "PCM Playback Volume" -@@ -45,7 +45,7 @@ PMacToonie.pcm.default { - type plug - slave.pcm { - @func concat -- strings [ "dsnoop:CARD=" $CARD ",FORMAT=S16" ] -+ strings [ "dsnoop:CARD=" $CARD ",FORMAT=S16_BE" ] - } - } - } -diff -r 9005d28a1f9e src/conf/cards/PS3.conf ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/src/conf/cards/PS3.conf Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,46 @@ -+# -+# Configuration for PS3 -+# -+ -+ -+ -+PS3.pcm.front.0 { -+ @args [ CARD ] -+ @args.CARD { -+ type string -+ } -+ type softvol -+ slave.pcm { -+ type hw -+ card $CARD -+ device 0 -+ } -+ control { -+ name "PCM Playback Volume" -+ card $CARD -+ } -+} -+ -+# default with dmix+softvol -+PS3.pcm.default { -+ @args [ CARD ] -+ @args.CARD { -+ type string -+ } -+ type asym -+ playback.pcm { -+ type plug -+ slave.pcm { -+ type softvol -+ slave.pcm { -+ @func concat -+ #strings [ "dmix:CARD=" $CARD ] -+ strings [ "dmix:CARD=" $CARD ",FORMAT=S16" ] -+ } -+ control { -+ name "PCM Playback Volume" -+ card $CARD -+ } -+ } -+ } -+} -diff -r 9005d28a1f9e src/conf/smixer.conf ---- a/src/conf/smixer.conf Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/conf/smixer.conf Tue Aug 14 16:14:08 2007 +0200 -@@ -1,3 +1,4 @@ usb { -+_full smixer-python.so - usb { - searchl "USB" - lib smixer-usb.so -diff -r 9005d28a1f9e src/control/namehint.c ---- a/src/control/namehint.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/control/namehint.c Tue Aug 14 16:14:08 2007 +0200 -@@ -90,6 +90,7 @@ static int get_dev_name1(struct hint_lis - if (list->device < 0) - return 0; - switch (list->iface) { -+#ifdef BUILD_HWDEP - case SND_CTL_ELEM_IFACE_HWDEP: - { - snd_hwdep_info_t *info; -@@ -100,6 +101,8 @@ static int get_dev_name1(struct hint_lis - *res = strdup(snd_hwdep_info_get_name(info)); - return 0; - } -+#endif -+#ifdef BUILD_PCM - case SND_CTL_ELEM_IFACE_PCM: - { - snd_pcm_info_t *info; -@@ -118,6 +121,8 @@ static int get_dev_name1(struct hint_lis - *res = strdup(snd_pcm_info_get_name(info)); - return 0; - } -+#endif -+#ifdef BUILD_RAWMIDI - case SND_CTL_ELEM_IFACE_RAWMIDI: - { - snd_rawmidi_info_t *info; -@@ -129,6 +134,7 @@ static int get_dev_name1(struct hint_lis - *res = strdup(snd_rawmidi_info_get_name(info)); - return 0; - } -+#endif - default: - return 0; - } -diff -r 9005d28a1f9e src/mixer/simple.c ---- a/src/mixer/simple.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/mixer/simple.c Tue Aug 14 16:14:08 2007 +0200 -@@ -38,7 +38,6 @@ - #include - #include "mixer_local.h" - #include "mixer_simple.h" --#include "alisp.h" - - /** - * \brief Register mixer simple element class -diff -r 9005d28a1f9e src/mixer/simple_abst.c ---- a/src/mixer/simple_abst.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/mixer/simple_abst.c Tue Aug 14 16:14:08 2007 +0200 -@@ -55,6 +55,9 @@ typedef struct _class_priv { - } class_priv_t; - - typedef int (*snd_mixer_sbasic_init_t)(snd_mixer_class_t *class); -+typedef int (*snd_mixer_sfbasic_init_t)(snd_mixer_class_t *class, -+ snd_mixer_t *mixer, -+ const char *device); - - #endif /* !DOC_HIDDEN */ - -@@ -62,10 +65,10 @@ static int try_open(snd_mixer_class_t *c - { - class_priv_t *priv = snd_mixer_class_get_private(class); - snd_mixer_event_t event_func; -- snd_mixer_sbasic_init_t init_func; -+ snd_mixer_sbasic_init_t init_func = NULL; - char *xlib, *path; - void *h; -- int err; -+ int err = 0; - - path = getenv("ALSA_MIXER_SIMPLE_MODULES"); - if (!path) -@@ -82,28 +85,71 @@ static int try_open(snd_mixer_class_t *c - free(xlib); - return -ENXIO; - } -+ priv->dlhandle = h; - event_func = snd_dlsym(h, "alsa_mixer_simple_event", NULL); - if (event_func == NULL) { - SNDERR("Symbol 'alsa_mixer_simple_event' was not found in '%s'", xlib); -- snd_dlclose(h); -+ err = -ENXIO; -+ } -+ if (err == 0) { -+ init_func = snd_dlsym(h, "alsa_mixer_simple_init", NULL); -+ if (init_func == NULL) { -+ SNDERR("Symbol 'alsa_mixer_simple_init' was not found in '%s'", xlib); -+ err = -ENXIO; -+ } -+ } -+ free(xlib); -+ err = err == 0 ? init_func(class) : err; -+ if (err < 0) -+ return err; -+ snd_mixer_class_set_event(class, event_func); -+ return 1; -+} -+ -+static int try_open_full(snd_mixer_class_t *class, snd_mixer_t *mixer, -+ const char *lib, const char *device) -+{ -+ class_priv_t *priv = snd_mixer_class_get_private(class); -+ snd_mixer_event_t event_func; -+ snd_mixer_sfbasic_init_t init_func = NULL; -+ char *xlib, *path; -+ void *h; -+ int err = 0; -+ -+ path = getenv("ALSA_MIXER_SIMPLE_MODULES"); -+ if (!path) -+ path = SO_PATH; -+ xlib = malloc(strlen(lib) + strlen(path) + 1 + 1); -+ if (xlib == NULL) -+ return -ENOMEM; -+ strcpy(xlib, path); -+ strcat(xlib, "/"); -+ strcat(xlib, lib); -+ /* note python modules requires RTLD_GLOBAL */ -+ h = snd_dlopen(xlib, RTLD_NOW|RTLD_GLOBAL); -+ if (h == NULL) { -+ SNDERR("Unable to open library '%s'", xlib); - free(xlib); - return -ENXIO; - } -- init_func = snd_dlsym(h, "alsa_mixer_simple_init", NULL); -- if (init_func == NULL) { -- SNDERR("Symbol 'alsa_mixer_simple_init' was not found in '%s'", xlib); -- snd_dlclose(h); -- free(xlib); -- return -ENXIO; -+ priv->dlhandle = h; -+ event_func = snd_dlsym(h, "alsa_mixer_simple_event", NULL); -+ if (event_func == NULL) { -+ SNDERR("Symbol 'alsa_mixer_simple_event' was not found in '%s'", xlib); -+ err = -ENXIO; -+ } -+ if (err == 0) { -+ init_func = snd_dlsym(h, "alsa_mixer_simple_finit", NULL); -+ if (init_func == NULL) { -+ SNDERR("Symbol 'alsa_mixer_simple_finit' was not found in '%s'", xlib); -+ err = -ENXIO; -+ } - } - free(xlib); -- err = init_func(class); -- if (err < 0) { -- snd_dlclose(h); -+ err = err == 0 ? init_func(class, mixer, device) : err; -+ if (err < 0) - return err; -- } - snd_mixer_class_set_event(class, event_func); -- priv->dlhandle = h; - return 1; - } - -@@ -126,6 +172,31 @@ static int match(snd_mixer_class_t *clas - return 0; - } - -+static int find_full(snd_mixer_class_t *class, snd_mixer_t *mixer, -+ snd_config_t *top, const char *device) -+{ -+ snd_config_iterator_t i, next; -+ char *lib; -+ const char *id; -+ int err; -+ -+ snd_config_for_each(i, next, top) { -+ snd_config_t *n = snd_config_iterator_entry(i); -+ if (snd_config_get_id(n, &id) < 0) -+ continue; -+ if (strcmp(id, "_full")) -+ continue; -+ err = snd_config_get_string(n, (const char **)&lib); -+ if (err < 0) -+ return err; -+ err = try_open_full(class, mixer, lib, device); -+ if (err < 0) -+ return err; -+ return 0; -+ } -+ return -ENOENT; -+} -+ - static int find_module(snd_mixer_class_t *class, snd_config_t *top) - { - snd_config_iterator_t i, next; -@@ -137,6 +208,8 @@ static int find_module(snd_mixer_class_t - snd_config_for_each(i, next, top) { - snd_config_t *n = snd_config_iterator_entry(i); - if (snd_config_get_id(n, &id) < 0) -+ continue; -+ if (*id == '_') - continue; - searchl = NULL; - lib = NULL; -@@ -223,20 +296,6 @@ int snd_mixer_simple_basic_register(snd_ - snd_mixer_class_set_compare(class, snd_mixer_selem_compare); - snd_mixer_class_set_private(class, priv); - snd_mixer_class_set_private_free(class, private_free); -- err = snd_ctl_open(&priv->ctl, priv->device, 0); -- if (err < 0) { -- SNDERR("unable to open control device '%s': %s", priv->device, snd_strerror(err)); -- goto __error; -- } -- err = snd_hctl_open_ctl(&priv->hctl, priv->ctl); -- if (err < 0) -- goto __error; -- err = snd_ctl_card_info_malloc(&priv->info); -- if (err < 0) -- goto __error; -- err = snd_ctl_card_info(priv->ctl, priv->info); -- if (err < 0) -- goto __error; - file = getenv("ALSA_MIXER_SIMPLE"); - if (!file) - file = ALSA_CONFIG_DIR "/smixer.conf"; -@@ -253,16 +312,35 @@ int snd_mixer_simple_basic_register(snd_ - SNDERR("%s may be old or corrupted: consider to remove or fix it", file); - goto __error; - } -+ err = find_full(class, mixer, top, priv->device); -+ if (err >= 0) -+ goto __full; -+ } -+ if (err >= 0) { -+ err = snd_ctl_open(&priv->ctl, priv->device, 0); -+ if (err < 0) { -+ SNDERR("unable to open control device '%s': %s", priv->device, snd_strerror(err)); -+ goto __error; -+ } -+ err = snd_hctl_open_ctl(&priv->hctl, priv->ctl); -+ if (err < 0) -+ goto __error; -+ err = snd_ctl_card_info_malloc(&priv->info); -+ if (err < 0) -+ goto __error; -+ err = snd_ctl_card_info(priv->ctl, priv->info); -+ if (err < 0) -+ goto __error; -+ } -+ if (err >= 0) - err = find_module(class, top); -- snd_config_delete(top); -- top = NULL; -- } - if (err >= 0) - err = snd_mixer_attach_hctl(mixer, priv->hctl); - if (err >= 0) { - priv->attach_flag = 1; - err = snd_mixer_class_register(class, mixer); - } -+ __full: - if (err < 0) { - __error: - if (top) -diff -r 9005d28a1f9e src/pcm/Makefile.am ---- a/src/pcm/Makefile.am Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/Makefile.am Tue Aug 14 16:14:08 2007 +0200 -@@ -99,6 +99,9 @@ if BUILD_PCM_PLUGIN_IOPLUG - if BUILD_PCM_PLUGIN_IOPLUG - libpcm_la_SOURCES += pcm_ioplug.c - endif -+if BUILD_PCM_PLUGIN_MMAP_EMUL -+libpcm_la_SOURCES += pcm_mmap_emul.c -+endif - - EXTRA_DIST = pcm_dmix_i386.c pcm_dmix_x86_64.c pcm_dmix_generic.c - -diff -r 9005d28a1f9e src/pcm/pcm.c ---- a/src/pcm/pcm.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm.c Tue Aug 14 16:14:08 2007 +0200 -@@ -1983,7 +1983,8 @@ static char *build_in_pcms[] = { - static char *build_in_pcms[] = { - "adpcm", "alaw", "copy", "dmix", "file", "hooks", "hw", "ladspa", "lfloat", - "linear", "meter", "mulaw", "multi", "null", "empty", "plug", "rate", "route", "share", -- "shm", "dsnoop", "dshare", "asym", "iec958", "softvol", NULL -+ "shm", "dsnoop", "dshare", "asym", "iec958", "softvol", "mmap_emul", -+ NULL - }; - - static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name, -diff -r 9005d28a1f9e src/pcm/pcm_dmix.c ---- a/src/pcm/pcm_dmix.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_dmix.c Tue Aug 14 16:14:08 2007 +0200 -@@ -139,12 +139,14 @@ static void dmix_server_free(snd_pcm_dir - * FIXME: optimize it for different architectures - */ - -+#include "pcm_dmix_generic.c" - #if defined(__i386__) - #include "pcm_dmix_i386.c" - #elif defined(__x86_64__) - #include "pcm_dmix_x86_64.c" - #else --#include "pcm_dmix_generic.c" -+#define mix_select_callbacks(x) generic_mix_select_callbacks(x) -+#define dmix_supported_format generic_dmix_supported_format - #endif - - static void mix_areas(snd_pcm_direct_t *dmix, -diff -r 9005d28a1f9e src/pcm/pcm_dmix_generic.c ---- a/src/pcm/pcm_dmix_generic.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_dmix_generic.c Tue Aug 14 16:14:08 2007 +0200 -@@ -119,14 +119,14 @@ static void mix_select_callbacks(snd_pcm - #else - - /* non-concurrent version, supporting both endians */ --static unsigned long long dmix_supported_format = -- (1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) | -- (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) | -- (1ULL << SND_PCM_FORMAT_S24_3LE); -+#define generic_dmix_supported_format \ -+ ((1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |\ -+ (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |\ -+ (1ULL << SND_PCM_FORMAT_S24_3LE)) - - #include - --static void mix_areas1_native(unsigned int size, -+static void generic_mix_areas1_native(unsigned int size, - volatile signed short *dst, signed short *src, - volatile signed int *sum, size_t dst_step, - size_t src_step, size_t sum_step) -@@ -155,7 +155,7 @@ static void mix_areas1_native(unsigned i - } - } - --static void mix_areas2_native(unsigned int size, -+static void generic_mix_areas2_native(unsigned int size, - volatile signed int *dst, signed int *src, - volatile signed int *sum, size_t dst_step, - size_t src_step, size_t sum_step) -@@ -186,7 +186,7 @@ static void mix_areas2_native(unsigned i - } - } - --static void mix_areas1_swap(unsigned int size, -+static void generic_mix_areas1_swap(unsigned int size, - volatile signed short *dst, signed short *src, - volatile signed int *sum, size_t dst_step, - size_t src_step, size_t sum_step) -@@ -215,7 +215,7 @@ static void mix_areas1_swap(unsigned int - } - } - --static void mix_areas2_swap(unsigned int size, -+static void generic_mix_areas2_swap(unsigned int size, - volatile signed int *dst, signed int *src, - volatile signed int *sum, size_t dst_step, - size_t src_step, size_t sum_step) -@@ -247,7 +247,7 @@ static void mix_areas2_swap(unsigned int - } - - /* always little endian */ --static void mix_areas3(unsigned int size, -+static void generic_mix_areas3(unsigned int size, - volatile unsigned char *dst, unsigned char *src, - volatile signed int *sum, size_t dst_step, - size_t src_step, size_t sum_step) -@@ -278,16 +278,16 @@ static void mix_areas3(unsigned int size - } - - --static void mix_select_callbacks(snd_pcm_direct_t *dmix) -+static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix) - { - if (snd_pcm_format_cpu_endian(dmix->shmptr->s.format)) { -- dmix->u.dmix.mix_areas1 = mix_areas1_native; -- dmix->u.dmix.mix_areas2 = mix_areas2_native; -+ dmix->u.dmix.mix_areas1 = generic_mix_areas1_native; -+ dmix->u.dmix.mix_areas2 = generic_mix_areas2_native; - } else { -- dmix->u.dmix.mix_areas1 = mix_areas1_swap; -- dmix->u.dmix.mix_areas2 = mix_areas2_swap; -- } -- dmix->u.dmix.mix_areas3 = mix_areas3; --} -- --#endif -+ dmix->u.dmix.mix_areas1 = generic_mix_areas1_swap; -+ dmix->u.dmix.mix_areas2 = generic_mix_areas2_swap; -+ } -+ dmix->u.dmix.mix_areas3 = generic_mix_areas3; -+} -+ -+#endif -diff -r 9005d28a1f9e src/pcm/pcm_dmix_i386.c ---- a/src/pcm/pcm_dmix_i386.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_dmix_i386.c Tue Aug 14 16:14:08 2007 +0200 -@@ -30,33 +30,45 @@ - #undef MIX_AREAS3_CMOV - #undef LOCK_PREFIX - --static unsigned long long dmix_supported_format = -- (1ULL << SND_PCM_FORMAT_S16_LE) | -- (1ULL << SND_PCM_FORMAT_S32_LE) | -- (1ULL << SND_PCM_FORMAT_S24_3LE); -+#define i386_dmix_supported_format \ -+ ((1ULL << SND_PCM_FORMAT_S16_LE) |\ -+ (1ULL << SND_PCM_FORMAT_S32_LE) |\ -+ (1ULL << SND_PCM_FORMAT_S24_3LE)) -+ -+#define dmix_supported_format \ -+ (i386_dmix_supported_format | generic_dmix_supported_format) - - static void mix_select_callbacks(snd_pcm_direct_t *dmix) - { -- FILE *in; -- char line[255]; -- int smp = 0, mmx = 0, cmov = 0; -+ static int smp = 0, mmx = 0, cmov = 0; -+ -+ if (!((1ULL<< dmix->shmptr->s.format) & i386_dmix_supported_format)) { -+ generic_mix_select_callbacks(dmix); -+ return; -+ } -+ -+ if (!smp) { -+ FILE *in; -+ char line[255]; - -- /* try to determine the capabilities of the CPU */ -- in = fopen("/proc/cpuinfo", "r"); -- if (in) { -- while (!feof(in)) { -- fgets(line, sizeof(line), in); -- if (!strncmp(line, "processor", 9)) -- smp++; -- else if (!strncmp(line, "flags", 5)) { -- if (strstr(line, " mmx")) -- mmx = 1; -- if (strstr(line, " cmov")) -- cmov = 1; -+ /* try to determine the capabilities of the CPU */ -+ in = fopen("/proc/cpuinfo", "r"); -+ if (in) { -+ while (!feof(in)) { -+ fgets(line, sizeof(line), in); -+ if (!strncmp(line, "processor", 9)) -+ smp++; -+ else if (!strncmp(line, "flags", 5)) { -+ if (strstr(line, " mmx")) -+ mmx = 1; -+ if (strstr(line, " cmov")) -+ cmov = 1; -+ } - } -+ fclose(in); - } -- fclose(in); - } -+ - if (mmx) { - dmix->u.dmix.mix_areas1 = smp > 1 ? mix_areas1_smp_mmx : mix_areas1_mmx; - } else { -diff -r 9005d28a1f9e src/pcm/pcm_dmix_x86_64.c ---- a/src/pcm/pcm_dmix_x86_64.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_dmix_x86_64.c Tue Aug 14 16:14:08 2007 +0200 -@@ -22,26 +22,37 @@ - #undef MIX_AREAS3 - #undef LOCK_PREFIX - --static unsigned long long dmix_supported_format = -- (1ULL << SND_PCM_FORMAT_S16_LE) | -- (1ULL << SND_PCM_FORMAT_S32_LE) | -- (1ULL << SND_PCM_FORMAT_S24_3LE); -+#define x86_64_dmix_supported_format \ -+ ((1ULL << SND_PCM_FORMAT_S16_LE) |\ -+ (1ULL << SND_PCM_FORMAT_S32_LE) |\ -+ (1ULL << SND_PCM_FORMAT_S24_3LE)) -+ -+#define dmix_supported_format \ -+ (x86_64_dmix_supported_format | generic_dmix_supported_format) - - static void mix_select_callbacks(snd_pcm_direct_t *dmix) - { -- FILE *in; -- char line[255]; -- int smp = 0; -+ static int smp = 0; - -- /* try to determine, if we have SMP */ -- in = fopen("/proc/cpuinfo", "r"); -- if (in) { -- while (!feof(in)) { -- fgets(line, sizeof(line), in); -- if (!strncmp(line, "processor", 9)) -- smp++; -+ if (!((1ULL<< dmix->shmptr->s.format) & x86_64_dmix_supported_format)) { -+ generic_mix_select_callbacks(dmix); -+ return; -+ } -+ -+ if (!smp) { -+ FILE *in; -+ char line[255]; -+ -+ /* try to determine, if we have SMP */ -+ in = fopen("/proc/cpuinfo", "r"); -+ if (in) { -+ while (!feof(in)) { -+ fgets(line, sizeof(line), in); -+ if (!strncmp(line, "processor", 9)) -+ smp++; -+ } -+ fclose(in); - } -- fclose(in); - } - // printf("SMP: %i\n", smp); - dmix->u.dmix.mix_areas1 = smp > 1 ? mix_areas1_smp : mix_areas1; -diff -r 9005d28a1f9e src/pcm/pcm_hw.c ---- a/src/pcm/pcm_hw.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_hw.c Tue Aug 14 16:14:08 2007 +0200 -@@ -88,14 +88,11 @@ typedef struct { - int version; - int fd; - int card, device, subdevice; -- int mmap_emulation; - int sync_ptr_ioctl; - volatile struct sndrv_pcm_mmap_status * mmap_status; - struct sndrv_pcm_mmap_control *mmap_control; - struct sndrv_pcm_sync_ptr *sync_ptr; -- int shadow_appl_ptr: 1, -- avail_update_flag: 1, -- mmap_shm: 1; -+ snd_pcm_uframes_t hw_ptr; - snd_pcm_uframes_t appl_ptr; - /* restricted parameters */ - snd_pcm_format_t format; -@@ -108,9 +105,6 @@ typedef struct { - #define SNDRV_PCM_VERSION_MAX SNDRV_PROTOCOL_VERSION(2, 0, 5) - - /* update appl_ptr with driver */ --#define UPDATE_SHADOW_PTR(hw) \ -- do { if (hw->shadow_appl_ptr && !hw->avail_update_flag) \ -- hw->appl_ptr = hw->mmap_control->appl_ptr; } while (0) - #define FAST_PCM_STATE(hw) \ - ((enum sndrv_pcm_state) (hw)->mmap_status->state) - #define FAST_PCM_TSTAMP(hw) \ -@@ -246,73 +240,10 @@ static int snd_pcm_hw_hw_refine(snd_pcm_ - return err; - } - -- if (hw->mmap_emulation) { -- int err = 0; -- snd_pcm_access_mask_t oldmask = *snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS); -- snd_pcm_access_mask_t mask; -- const snd_mask_t *pmask; -- -- snd_mask_empty(&mask); -- if (hw_refine_call(hw, params) < 0) -- err = -errno; -- if (err < 0) { -- snd_pcm_hw_params_t new = *params; -- -- if (!(params->rmask & (1<cmask |= 1<cmask |= 1<cmask |= 1<cmask |= 1<private_data; - int err; -- if (hw->mmap_emulation) { -- snd_pcm_hw_params_t old = *params; -- if (hw_params_call(hw, params) < 0) { -- snd_pcm_access_t access; -- snd_pcm_access_mask_t oldmask; -- const snd_mask_t *pmask; -- -- *params = old; -- pmask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS); -- oldmask = *(snd_pcm_access_mask_t *)pmask; -- if (INTERNAL(snd_pcm_hw_params_get_access)(params, &access) < 0) -- goto _err; -- switch (access) { -- case SND_PCM_ACCESS_MMAP_INTERLEAVED: -- snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask, SND_PCM_ACCESS_MMAP_INTERLEAVED); -- snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask, SND_PCM_ACCESS_RW_INTERLEAVED); -- break; -- case SND_PCM_ACCESS_MMAP_NONINTERLEAVED: -- snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); -- snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask, SND_PCM_ACCESS_RW_NONINTERLEAVED); -- break; -- default: -- goto _err; -- } -- if (hw_params_call(hw, params) < 0) -- goto _err; -- hw->mmap_shm = 1; -- *(snd_pcm_access_mask_t *)pmask = oldmask; -- } -- } else { -- if (hw_params_call(hw, params) < 0) { -- _err: -- err = -errno; -- SYSMSG("SNDRV_PCM_IOCTL_HW_PARAMS failed"); -- return err; -- } -+ if (hw_params_call(hw, params) < 0) { -+ err = -errno; -+ SYSMSG("SNDRV_PCM_IOCTL_HW_PARAMS failed"); -+ return err; - } - err = sync_ptr(hw, 0); - if (err < 0) - return err; - if (pcm->stream == SND_PCM_STREAM_CAPTURE) { -- if (hw->mmap_shm) { -- hw->shadow_appl_ptr = 1; -- hw->appl_ptr = 0; -- snd_pcm_set_appl_ptr(pcm, &hw->appl_ptr, -1, 0); -- } else { -- hw->shadow_appl_ptr = 0; -- snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd, SNDRV_PCM_MMAP_OFFSET_CONTROL); -- } -+ snd_pcm_set_appl_ptr(pcm, &hw->mmap_control->appl_ptr, hw->fd, -+ SNDRV_PCM_MMAP_OFFSET_CONTROL); - } - return 0; - } -@@ -431,16 +324,13 @@ static int snd_pcm_hw_channel_info(snd_p - return err; - } - info->channel = i.channel; -- if (!hw->mmap_shm) { -- info->addr = 0; -- info->first = i.first; -- info->step = i.step; -- info->type = SND_PCM_AREA_MMAP; -- info->u.mmap.fd = fd; -- info->u.mmap.offset = i.offset; -- return 0; -- } -- return snd_pcm_channel_info_shm(pcm, info, -1); -+ info->addr = 0; -+ info->first = i.first; -+ info->step = i.step; -+ info->type = SND_PCM_AREA_MMAP; -+ info->u.mmap.fd = fd; -+ info->u.mmap.offset = i.offset; -+ return 0; - } - - static int snd_pcm_hw_status(snd_pcm_t *pcm, snd_pcm_status_t * status) -@@ -781,7 +671,6 @@ static snd_pcm_sframes_t snd_pcm_hw_read - #endif - if (err < 0) - return snd_pcm_check_error(pcm, err); -- UPDATE_SHADOW_PTR(hw); - return xferi.result; - } - -@@ -801,7 +690,6 @@ static snd_pcm_sframes_t snd_pcm_hw_read - #endif - if (err < 0) - return snd_pcm_check_error(pcm, err); -- UPDATE_SHADOW_PTR(hw); - return xfern.result; - } - -@@ -925,22 +813,6 @@ static snd_pcm_sframes_t snd_pcm_hw_mmap - { - snd_pcm_hw_t *hw = pcm->private_data; - -- if (hw->mmap_shm) { -- if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { -- snd_pcm_sframes_t result = 0, res; -- -- do { -- res = snd_pcm_write_mmap(pcm, size); -- if (res < 0) -- return result > 0 ? result : res; -- size -= res; -- result += res; -- } while (size > 0); -- return result; -- } else { -- assert(hw->shadow_appl_ptr); -- } -- } - snd_pcm_mmap_appl_forward(pcm, size); - sync_ptr(hw, 0); - #ifdef DEBUG_MMAP -@@ -955,23 +827,7 @@ static snd_pcm_sframes_t snd_pcm_hw_avai - snd_pcm_uframes_t avail; - - sync_ptr(hw, 0); -- if (pcm->stream == SND_PCM_STREAM_PLAYBACK) { -- avail = snd_pcm_mmap_playback_avail(pcm); -- } else { -- avail = snd_pcm_mmap_capture_avail(pcm); -- if (avail > 0 && hw->mmap_shm) { -- snd_pcm_sframes_t err; -- snd_pcm_hw_t *hw = pcm->private_data; -- hw->avail_update_flag = 1; -- err = snd_pcm_read_mmap(pcm, avail); -- hw->avail_update_flag = 0; -- if (err < 0) -- return err; -- if ((snd_pcm_uframes_t)err != avail) -- SNDMSG("short read %ld for avail %ld", err, avail); -- return err; -- } -- } -+ avail = snd_pcm_mmap_avail(pcm); - switch (FAST_PCM_STATE(hw)) { - case SNDRV_PCM_STATE_RUNNING: - if (avail >= pcm->stop_threshold) { -@@ -1058,7 +914,7 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fas - * \param pcmp Returns created PCM handle - * \param name Name of PCM - * \param fd File descriptor -- * \param mmap_emulation Boolean flag for mmap emulation mode -+ * \param mmap_emulation Obsoleted parameter - * \param sync_ptr_ioctl Boolean flag for sync_ptr ioctl - * \retval zero on success otherwise a negative error code - * \warning Using of this function might be dangerous in the sense -@@ -1066,7 +922,8 @@ static snd_pcm_fast_ops_t snd_pcm_hw_fas - * changed in future. - */ - int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, const char *name, -- int fd, int mmap_emulation, int sync_ptr_ioctl) -+ int fd, int mmap_emulation ATTRIBUTE_UNUSED, -+ int sync_ptr_ioctl) - { - int ver; - long fmode; -@@ -1139,7 +996,6 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, - hw->device = info.device; - hw->subdevice = info.subdevice; - hw->fd = fd; -- hw->mmap_emulation = mmap_emulation; - hw->sync_ptr_ioctl = sync_ptr_ioctl; - /* no restriction */ - hw->format = SND_PCM_FORMAT_UNKNOWN; -@@ -1159,8 +1015,6 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, - pcm->poll_fd = fd; - pcm->poll_events = info.stream == SND_PCM_STREAM_PLAYBACK ? POLLOUT : POLLIN; - -- *pcmp = pcm; -- - ret = snd_pcm_hw_mmap_status(pcm); - if (ret < 0) { - snd_pcm_close(pcm); -@@ -1171,6 +1025,8 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, - snd_pcm_close(pcm); - return ret; - } -+ -+ *pcmp = pcm; - return 0; - } - -@@ -1183,7 +1039,7 @@ int snd_pcm_hw_open_fd(snd_pcm_t **pcmp, - * \param subdevice Number of subdevice - * \param stream PCM Stream - * \param mode PCM Mode -- * \param mmap_emulation Emulate mmap access using standard r/w access -+ * \param mmap_emulation Obsoleted parameter - * \param sync_ptr_ioctl Use SYNC_PTR ioctl rather than mmap for control structures - * \retval zero on success otherwise a negative error code - * \warning Using of this function might be dangerous in the sense -@@ -1193,7 +1049,8 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, co - int snd_pcm_hw_open(snd_pcm_t **pcmp, const char *name, - int card, int device, int subdevice, - snd_pcm_stream_t stream, int mode, -- int mmap_emulation, int sync_ptr_ioctl) -+ int mmap_emulation ATTRIBUTE_UNUSED, -+ int sync_ptr_ioctl) - { - char filename[sizeof(SNDRV_FILE_PCM_STREAM_PLAYBACK) + 20]; - const char *filefmt; -@@ -1255,7 +1112,7 @@ int snd_pcm_hw_open(snd_pcm_t **pcmp, co - } - } - snd_ctl_close(ctl); -- return snd_pcm_hw_open_fd(pcmp, name, fd, mmap_emulation, sync_ptr_ioctl); -+ return snd_pcm_hw_open_fd(pcmp, name, fd, 0, sync_ptr_ioctl); - _err: - snd_ctl_close(ctl); - return ret; -@@ -1281,7 +1138,6 @@ pcm.name { - card INT/STR # Card name (string) or number (integer) - [device INT] # Device number (default 0) - [subdevice INT] # Subdevice number (default -1: first available) -- [mmap_emulation BOOL] # Enable mmap emulation for ro/wo devices - [sync_ptr_ioctl BOOL] # Use SYNC_PTR ioctl rather than the direct mmap access for control structures - [nonblock BOOL] # Force non-blocking open mode - [format STR] # Restrict only to the given format -@@ -1318,7 +1174,7 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, c - snd_config_iterator_t i, next; - long card = -1, device = 0, subdevice = -1; - const char *str; -- int err, mmap_emulation = 0, sync_ptr_ioctl = 0; -+ int err, sync_ptr_ioctl = 0; - int rate = 0, channels = 0; - snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN; - snd_config_t *n; -@@ -1370,13 +1226,6 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, c - } - continue; - } -- if (strcmp(id, "mmap_emulation") == 0) { -- err = snd_config_get_bool(n); -- if (err < 0) -- continue; -- mmap_emulation = err; -- continue; -- } - if (strcmp(id, "sync_ptr_ioctl") == 0) { - err = snd_config_get_bool(n); - if (err < 0) -@@ -1429,7 +1278,7 @@ int _snd_pcm_hw_open(snd_pcm_t **pcmp, c - } - err = snd_pcm_hw_open(pcmp, name, card, device, subdevice, stream, - mode | (nonblock ? SND_PCM_NONBLOCK : 0), -- mmap_emulation, sync_ptr_ioctl); -+ 0, sync_ptr_ioctl); - if (err < 0) - return err; - if (nonblock && ! (mode & SND_PCM_NONBLOCK)) { -diff -r 9005d28a1f9e src/pcm/pcm_local.h ---- a/src/pcm/pcm_local.h Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_local.h Tue Aug 14 16:14:08 2007 +0200 -@@ -266,8 +266,10 @@ snd_pcm_sframes_t snd_pcm_write_areas(sn - snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_t *areas, - snd_pcm_uframes_t offset, snd_pcm_uframes_t size, - snd_pcm_xfer_areas_func_t func); --snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size); --snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size); -+snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset, -+ snd_pcm_uframes_t size); -+snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset, -+ snd_pcm_uframes_t size); - static inline int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info) - { - return pcm->ops->channel_info(pcm, info); -diff -r 9005d28a1f9e src/pcm/pcm_mmap.c ---- a/src/pcm/pcm_mmap.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_mmap.c Tue Aug 14 16:14:08 2007 +0200 -@@ -531,7 +531,8 @@ int snd_pcm_munmap(snd_pcm_t *pcm) - return 0; - } - --snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size) -+snd_pcm_sframes_t snd_pcm_write_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset, -+ snd_pcm_uframes_t size) - { - snd_pcm_uframes_t xfer = 0; - snd_pcm_sframes_t err = 0; -@@ -539,7 +540,6 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd - return 0; - while (xfer < size) { - snd_pcm_uframes_t frames = size - xfer; -- snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); - snd_pcm_uframes_t cont = pcm->buffer_size - offset; - if (cont < frames) - frames = cont; -@@ -575,13 +575,15 @@ snd_pcm_sframes_t snd_pcm_write_mmap(snd - if (err < 0) - break; - xfer += frames; -+ offset += frames; - } - if (xfer > 0) - return xfer; - return err; - } - --snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t size) -+snd_pcm_sframes_t snd_pcm_read_mmap(snd_pcm_t *pcm, snd_pcm_uframes_t offset, -+ snd_pcm_uframes_t size) - { - snd_pcm_uframes_t xfer = 0; - snd_pcm_sframes_t err = 0; -@@ -589,7 +591,6 @@ snd_pcm_sframes_t snd_pcm_read_mmap(snd_ - return 0; - while (xfer < size) { - snd_pcm_uframes_t frames = size - xfer; -- snd_pcm_uframes_t offset = snd_pcm_mmap_hw_offset(pcm); - snd_pcm_uframes_t cont = pcm->buffer_size - offset; - if (cont < frames) - frames = cont; -@@ -624,6 +625,7 @@ snd_pcm_sframes_t snd_pcm_read_mmap(snd_ - if (err < 0) - break; - xfer += frames; -+ offset += frames; - } - if (xfer > 0) - return xfer; -diff -r 9005d28a1f9e src/pcm/pcm_mmap_emul.c ---- /dev/null Thu Jan 01 00:00:00 1970 +0000 -+++ b/src/pcm/pcm_mmap_emul.c Tue Aug 14 16:14:08 2007 +0200 -@@ -0,0 +1,485 @@ -+/** -+ * \file pcm/pcm_mmap_emul.c -+ * \ingroup PCM_Plugins -+ * \brief PCM Mmap-Emulation Plugin Interface -+ * \author Takashi Iwai -+ * \date 2007 -+ */ -+/* -+ * PCM - Mmap-Emulation -+ * Copyright (c) 2007 by Takashi Iwai -+ * -+ * -+ * This library is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Lesser General Public License as -+ * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#include "pcm_local.h" -+#include "pcm_generic.h" -+ -+#ifndef PIC -+/* entry for static linking */ -+const char *_snd_module_pcm_mmap_emul = ""; -+#endif -+ -+/* -+ * -+ */ -+ -+typedef struct { -+ snd_pcm_generic_t gen; -+ unsigned int mmap_emul :1; -+ snd_pcm_uframes_t hw_ptr; -+ snd_pcm_uframes_t appl_ptr; -+} mmap_emul_t; -+ -+/* -+ * here goes a really tricky part; hw_refine falls back to ACCESS_RW_* type -+ * when ACCESS_MMAP_* isn't supported by the hardware. -+ */ -+static int snd_pcm_mmap_emul_hw_refine(snd_pcm_t *pcm, -+ snd_pcm_hw_params_t *params) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ int err = 0; -+ snd_pcm_access_mask_t oldmask = -+ *snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS); -+ snd_pcm_access_mask_t mask; -+ const snd_mask_t *pmask; -+ -+ snd_mask_none(&mask); -+ err = snd_pcm_hw_refine(map->gen.slave, params); -+ if (err < 0) { -+ /* try to use RW_* */ -+ snd_pcm_hw_params_t new = *params; -+ -+ if (!(params->rmask & (1<gen.slave, &new); -+ if (err < 0) -+ return err; -+ *params = new; -+ } -+ -+ pmask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS); -+ if (snd_pcm_access_mask_test(pmask, SND_PCM_ACCESS_MMAP_INTERLEAVED) || -+ snd_pcm_access_mask_test(pmask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED) || -+ snd_pcm_access_mask_test(pmask, SND_PCM_ACCESS_MMAP_COMPLEX)) -+ return 0; -+ if (snd_pcm_access_mask_test(&mask, SND_PCM_ACCESS_RW_INTERLEAVED)) { -+ if (snd_pcm_access_mask_test(pmask, -+ SND_PCM_ACCESS_RW_INTERLEAVED)) -+ snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask, -+ SND_PCM_ACCESS_MMAP_INTERLEAVED); -+ snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask, -+ SND_PCM_ACCESS_RW_INTERLEAVED); -+ params->cmask |= 1<cmask |= 1<cmask |= 1<cmask |= 1<private_data; -+ snd_pcm_hw_params_t old = *params; -+ snd_pcm_access_t access; -+ snd_pcm_access_mask_t oldmask; -+ const snd_mask_t *pmask; -+ int err; -+ -+ err = _snd_pcm_hw_params(map->gen.slave, params); -+ if (err >= 0) { -+ map->mmap_emul = 0; -+ return err; -+ } -+ -+ *params = old; -+ pmask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_ACCESS); -+ oldmask = *(snd_pcm_access_mask_t *)pmask; -+ if (INTERNAL(snd_pcm_hw_params_get_access)(params, &access) < 0) -+ goto _err; -+ switch (access) { -+ case SND_PCM_ACCESS_MMAP_INTERLEAVED: -+ snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask, -+ SND_PCM_ACCESS_MMAP_INTERLEAVED); -+ snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask, -+ SND_PCM_ACCESS_RW_INTERLEAVED); -+ break; -+ case SND_PCM_ACCESS_MMAP_NONINTERLEAVED: -+ snd_pcm_access_mask_reset((snd_pcm_access_mask_t *)pmask, -+ SND_PCM_ACCESS_MMAP_NONINTERLEAVED); -+ snd_pcm_access_mask_set((snd_pcm_access_mask_t *)pmask, -+ SND_PCM_ACCESS_RW_NONINTERLEAVED); -+ break; -+ default: -+ goto _err; -+ } -+ err = _snd_pcm_hw_params(map->gen.slave, params); -+ if (err < 0) -+ goto _err; -+ -+ /* need to back the access type to relieve apps */ -+ *(snd_pcm_access_mask_t *)pmask = oldmask; -+ -+ /* OK, we do fake */ -+ map->mmap_emul = 1; -+ map->appl_ptr = 0; -+ map->hw_ptr = 0; -+ snd_pcm_set_hw_ptr(pcm, &map->hw_ptr, -1, 0); -+ snd_pcm_set_appl_ptr(pcm, &map->appl_ptr, -1, 0); -+ return 0; -+ -+ _err: -+ err = -errno; -+ return err; -+} -+ -+static int snd_pcm_mmap_emul_prepare(snd_pcm_t *pcm) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ int err; -+ -+ err = snd_pcm_generic_prepare(pcm); -+ if (err < 0) -+ return err; -+ map->hw_ptr = map->appl_ptr = 0; -+ return err; -+} -+ -+static int snd_pcm_mmap_emul_reset(snd_pcm_t *pcm) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ int err; -+ -+ err = snd_pcm_generic_reset(pcm); -+ if (err < 0) -+ return err; -+ map->hw_ptr = map->appl_ptr = 0; -+ return err; -+} -+ -+static snd_pcm_sframes_t -+snd_pcm_mmap_emul_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames) -+{ -+ frames = snd_pcm_generic_rewind(pcm, frames); -+ if (frames > 0) -+ snd_pcm_mmap_appl_backward(pcm, frames); -+ return frames; -+} -+ -+static snd_pcm_sframes_t -+snd_pcm_mmap_emul_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames) -+{ -+ frames = snd_pcm_generic_forward(pcm, frames); -+ if (frames > 0) -+ snd_pcm_mmap_appl_forward(pcm, frames); -+ return frames; -+} -+ -+/* write out the uncommitted chunk on mmap buffer to the slave PCM */ -+static snd_pcm_sframes_t -+sync_slave_write(snd_pcm_t *pcm) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ snd_pcm_t *slave = map->gen.slave; -+ snd_pcm_uframes_t offset; -+ snd_pcm_sframes_t size; -+ -+ size = map->appl_ptr - *slave->appl.ptr; -+ if (size < 0) -+ size += pcm->boundary; -+ size -= size % pcm->xfer_align; -+ if (!size) -+ return 0; -+ offset = *slave->appl.ptr % pcm->buffer_size; -+ return snd_pcm_write_mmap(pcm, offset, size); -+} -+ -+/* read the available chunk on the slave PCM to mmap buffer */ -+static snd_pcm_sframes_t -+sync_slave_read(snd_pcm_t *pcm) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ snd_pcm_t *slave = map->gen.slave; -+ snd_pcm_uframes_t offset; -+ snd_pcm_sframes_t size; -+ -+ size = *slave->hw.ptr - map->hw_ptr; -+ if (size < 0) -+ size += pcm->boundary; -+ size -= size % pcm->xfer_align; -+ if (!size) -+ return 0; -+ offset = map->hw_ptr % pcm->buffer_size; -+ size = snd_pcm_read_mmap(pcm, offset, size); -+ if (size > 0) -+ snd_pcm_mmap_hw_forward(pcm, size); -+ return 0; -+} -+ -+static snd_pcm_sframes_t -+snd_pcm_mmap_emul_mmap_commit(snd_pcm_t *pcm, snd_pcm_uframes_t offset, -+ snd_pcm_uframes_t size) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ snd_pcm_t *slave = map->gen.slave; -+ -+ if (!map->mmap_emul) -+ return snd_pcm_mmap_commit(slave, offset, size); -+ snd_pcm_mmap_appl_forward(pcm, size); -+ if (pcm->stream == SND_PCM_STREAM_PLAYBACK) -+ sync_slave_write(pcm); -+ return size; -+} -+ -+static snd_pcm_sframes_t snd_pcm_mmap_emul_avail_update(snd_pcm_t *pcm) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ snd_pcm_t *slave = map->gen.slave; -+ snd_pcm_sframes_t avail; -+ -+ avail = snd_pcm_avail_update(slave); -+ if (!map->mmap_emul) -+ return avail; -+ -+ if (pcm->stream == SND_PCM_STREAM_PLAYBACK) -+ map->hw_ptr = *slave->hw.ptr; -+ else -+ sync_slave_read(pcm); -+ return snd_pcm_mmap_avail(pcm); -+} -+ -+static void snd_pcm_mmap_emul_dump(snd_pcm_t *pcm, snd_output_t *out) -+{ -+ mmap_emul_t *map = pcm->private_data; -+ -+ snd_output_printf(out, "Mmap emulation PCM\n"); -+ if (pcm->setup) { -+ snd_output_printf(out, "Its setup is:\n"); -+ snd_pcm_dump_setup(pcm, out); -+ } -+ snd_output_printf(out, "Slave: "); -+ snd_pcm_dump(map->gen.slave, out); -+} -+ -+static snd_pcm_ops_t snd_pcm_mmap_emul_ops = { -+ .close = snd_pcm_generic_close, -+ .info = snd_pcm_generic_info, -+ .hw_refine = snd_pcm_mmap_emul_hw_refine, -+ .hw_params = snd_pcm_mmap_emul_hw_params, -+ .hw_free = snd_pcm_generic_hw_free, -+ .sw_params = snd_pcm_generic_sw_params, -+ .channel_info = snd_pcm_generic_channel_info, -+ .dump = snd_pcm_mmap_emul_dump, -+ .nonblock = snd_pcm_generic_nonblock, -+ .async = snd_pcm_generic_async, -+ .mmap = snd_pcm_generic_mmap, -+ .munmap = snd_pcm_generic_munmap, -+}; -+ -+static snd_pcm_fast_ops_t snd_pcm_mmap_emul_fast_ops = { -+ .status = snd_pcm_generic_status, -+ .state = snd_pcm_generic_state, -+ .hwsync = snd_pcm_generic_hwsync, -+ .delay = snd_pcm_generic_delay, -+ .prepare = snd_pcm_mmap_emul_prepare, -+ .reset = snd_pcm_mmap_emul_reset, -+ .start = snd_pcm_generic_start, -+ .drop = snd_pcm_generic_drop, -+ .drain = snd_pcm_generic_drain, -+ .pause = snd_pcm_generic_pause, -+ .rewind = snd_pcm_mmap_emul_rewind, -+ .forward = snd_pcm_mmap_emul_forward, -+ .resume = snd_pcm_generic_resume, -+ .link = snd_pcm_generic_link, -+ .link_slaves = snd_pcm_generic_link_slaves, -+ .unlink = snd_pcm_generic_unlink, -+ .writei = snd_pcm_generic_writei, -+ .writen = snd_pcm_generic_writen, -+ .readi = snd_pcm_generic_readi, -+ .readn = snd_pcm_generic_readn, -+ .avail_update = snd_pcm_mmap_emul_avail_update, -+ .mmap_commit = snd_pcm_mmap_emul_mmap_commit, -+ .poll_descriptors = snd_pcm_generic_poll_descriptors, -+ .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count, -+ .poll_revents = snd_pcm_generic_poll_revents, -+}; -+ -+static int snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name, -+ snd_pcm_t *slave, int close_slave) -+{ -+ snd_pcm_t *pcm; -+ mmap_emul_t *map; -+ int err; -+ -+ map = calloc(1, sizeof(*map)); -+ if (!map) -+ return -ENOMEM; -+ map->gen.slave = slave; -+ map->gen.close_slave = close_slave; -+ -+ err = snd_pcm_new(&pcm, SND_PCM_TYPE_MMAP_EMUL, name, -+ slave->stream, slave->mode); -+ if (err < 0) { -+ free(map); -+ return err; -+ } -+ pcm->ops = &snd_pcm_mmap_emul_ops; -+ pcm->fast_ops = &snd_pcm_mmap_emul_fast_ops; -+ pcm->private_data = map; -+ pcm->poll_fd = slave->poll_fd; -+ pcm->poll_events = slave->poll_events; -+ snd_pcm_set_hw_ptr(pcm, &map->hw_ptr, -1, 0); -+ snd_pcm_set_appl_ptr(pcm, &map->appl_ptr, -1, 0); -+ *pcmp = pcm; -+ -+ return 0; -+} -+ -+/*! \page pcm_plugins -+ -+\section pcm_plugins_mmap_emul Plugin: mmap_emul -+ -+\code -+pcm.name { -+ type mmap_emul -+ slave PCM -+} -+\endcode -+ -+\subsection pcm_plugins_mmap_emul_funcref Function reference -+ -+
    -+
  • _snd_pcm_hw_open() -+
-+ -+*/ -+ -+/** -+ * \brief Creates a new mmap_emul PCM -+ * \param pcmp Returns created PCM handle -+ * \param name Name of PCM -+ * \param root Root configuration node -+ * \param conf Configuration node with hw PCM description -+ * \param stream PCM Stream -+ * \param mode PCM Mode -+ * \warning Using of this function might be dangerous in the sense -+ * of compatibility reasons. The prototype might be freely -+ * changed in future. -+ */ -+int _snd_pcm_mmap_emul_open(snd_pcm_t **pcmp, const char *name, -+ snd_config_t *root ATTRIBUTE_UNUSED, -+ snd_config_t *conf, -+ snd_pcm_stream_t stream, int mode) -+{ -+ snd_config_iterator_t i, next; -+ int err; -+ snd_pcm_t *spcm; -+ snd_config_t *slave = NULL, *sconf; -+ -+ snd_config_for_each(i, next, conf) { -+ snd_config_t *n = snd_config_iterator_entry(i); -+ const char *id; -+ if (snd_config_get_id(n, &id) < 0) -+ continue; -+ if (snd_pcm_conf_generic_id(id)) -+ continue; -+ if (strcmp(id, "slave") == 0) { -+ slave = n; -+ continue; -+ } -+ SNDERR("Unknown field %s", id); -+ return -EINVAL; -+ } -+ if (!slave) { -+ SNDERR("slave is not defined"); -+ return -EINVAL; -+ } -+ err = snd_pcm_slave_conf(root, slave, &sconf, 0); -+ if (err < 0) -+ return err; -+ err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf); -+ snd_config_delete(sconf); -+ if (err < 0) -+ return err; -+ err = snd_pcm_mmap_emul_open(pcmp, name, spcm, 1); -+ if (err < 0) -+ snd_pcm_close(spcm); -+ return err; -+} -+ -+#ifndef DOC_HIDDEN -+SND_DLSYM_BUILD_VERSION(_snd_pcm_mmap_emul_open, SND_PCM_DLSYM_VERSION); -+#endif -diff -r 9005d28a1f9e src/pcm/pcm_softvol.c ---- a/src/pcm/pcm_softvol.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_softvol.c Tue Aug 14 16:14:08 2007 +0200 -@@ -101,7 +101,7 @@ typedef union { - int i; - short s[2]; - } val_t; --static inline int MULTI_DIV_32x16(int a, unsigned short b, int swap) -+static inline int MULTI_DIV_32x16(int a, unsigned short b) - { - val_t v, x, y; - v.i = a; -@@ -123,7 +123,7 @@ static inline int MULTI_DIV_int(int a, u - unsigned int gain = (b >> VOL_SCALE_SHIFT); - int fraction; - a = swap ? (int)bswap_32(a) : a; -- fraction = MULTI_DIV_32x16(a, b & VOL_SCALE_MASK, swap); -+ fraction = MULTI_DIV_32x16(a, b & VOL_SCALE_MASK); - if (gain) { - long long amp = (long long)a * gain + fraction; - if (amp > (int)0x7fffffff) -diff -r 9005d28a1f9e src/pcm/pcm_symbols.c ---- a/src/pcm/pcm_symbols.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/pcm/pcm_symbols.c Tue Aug 14 16:14:08 2007 +0200 -@@ -49,6 +49,7 @@ extern const char *_snd_module_pcm_softv - extern const char *_snd_module_pcm_softvol; - extern const char *_snd_module_pcm_extplug; - extern const char *_snd_module_pcm_ioplug; -+extern const char *_snd_module_pcm_mmap_emul; - - static const char **snd_pcm_open_objects[] = { - &_snd_module_pcm_hw, -diff -r 9005d28a1f9e src/seq/seq_midi_event.c ---- a/src/seq/seq_midi_event.c Mon Jun 11 10:52:17 2007 +0200 -+++ b/src/seq/seq_midi_event.c Tue Aug 14 16:14:08 2007 +0200 -@@ -45,10 +45,9 @@ struct snd_midi_event { - }; - - --/* queue type */ --/* from 0 to 7 are normal commands (note off, on, etc.) */ --#define ST_NOTEOFF 0 --#define ST_NOTEON 1 -+/* event type, index into status_event[] */ -+/* from 0 to 6 are normal commands (note off, on, etc.) for 0x8?-0xe? */ -+#define ST_INVALID 7 - #define ST_SPECIAL 8 - #define ST_SYSEX ST_SPECIAL - /* from 8 to 15 are events for 0xf0-0xf7 */ -@@ -85,32 +84,33 @@ static struct status_event_list_t { - event_encode_t encode; - event_decode_t decode; - } status_event[] = { -- /* 0x80 - 0xf0 */ -- {SND_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode}, -- {SND_SEQ_EVENT_NOTEON, 2, note_event, note_decode}, -- {SND_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode}, -- {SND_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode}, -- {SND_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode}, -- {SND_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode}, -- {SND_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode}, -- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */ -+ /* 0x80 - 0xef */ -+ {SND_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode}, -+ {SND_SEQ_EVENT_NOTEON, 2, note_event, note_decode}, -+ {SND_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode}, -+ {SND_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode}, -+ {SND_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode}, -+ {SND_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode}, -+ {SND_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode}, -+ /* invalid */ -+ {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, - /* 0xf0 - 0xff */ -- {SND_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */ -- {SND_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */ -- {SND_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */ -- {SND_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */ -- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */ -- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */ -- {SND_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */ -- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */ -- {SND_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */ -- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */ -- {SND_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */ -- {SND_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */ -- {SND_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */ -- {SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */ -- {SND_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */ -- {SND_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */ -+ {SND_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */ -+ {SND_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */ -+ {SND_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */ -+ {SND_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */ -+ {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf4 */ -+ {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf5 */ -+ {SND_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */ -+ {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf7 */ -+ {SND_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */ -+ {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xf9 */ -+ {SND_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */ -+ {SND_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */ -+ {SND_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */ -+ {SND_SEQ_EVENT_NONE, -1, NULL, NULL}, /* 0xfd */ -+ {SND_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */ -+ {SND_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */ - }; - - static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, const snd_seq_event_t *ev); -@@ -153,6 +153,7 @@ int snd_midi_event_new(size_t bufsize, s - } - dev->bufsize = bufsize; - dev->lastcmd = 0xff; -+ dev->type = ST_INVALID; - *rdev = dev; - return 0; - } -@@ -191,7 +192,7 @@ inline static void reset_encode(snd_midi - { - dev->read = 0; - dev->qlen = 0; -- dev->type = 0; -+ dev->type = ST_INVALID; - } - - /** -@@ -307,28 +308,30 @@ int snd_midi_event_encode_byte(snd_midi_ - ev->type = status_event[ST_SPECIAL + c - 0xf0].event; - ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK; - ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED; -- return 1; -- } -- -- if (dev->qlen > 0) { -- /* rest of command */ -- dev->buf[dev->read++] = c; -- if (dev->type != ST_SYSEX) -- dev->qlen--; -+ return ev->type != SND_SEQ_EVENT_NONE; -+ } -+ -+ if ((c & 0x80) && -+ (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) { -+ /* new command */ -+ dev->buf[0] = c; -+ if ((c & 0xf0) == 0xf0) /* system message */ -+ dev->type = (c & 0x0f) + ST_SPECIAL; -+ else -+ dev->type = (c >> 4) & 0x07; -+ dev->read = 1; -+ dev->qlen = status_event[dev->type].qlen; - } else { -- /* new command */ -- dev->read = 1; -- if (c & 0x80) { -- dev->buf[0] = c; -- if ((c & 0xf0) == 0xf0) /* special events */ -- dev->type = (c & 0x0f) + ST_SPECIAL; -- else -- dev->type = (c >> 4) & 0x07; -- dev->qlen = status_event[dev->type].qlen; -+ if (dev->qlen > 0) { -+ /* rest of command */ -+ dev->buf[dev->read++] = c; -+ if (dev->type != ST_SYSEX) -+ dev->qlen--; - } else { -- /* process this byte as argument */ -- dev->buf[dev->read++] = c; -+ /* running status */ -+ dev->buf[1] = c; - dev->qlen = status_event[dev->type].qlen - 1; -+ dev->read = 2; - } - } - if (dev->qlen == 0) { -@@ -337,6 +340,8 @@ int snd_midi_event_encode_byte(snd_midi_ - ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED; - if (status_event[dev->type].encode) /* set data values */ - status_event[dev->type].encode(dev, ev); -+ if (dev->type >= ST_SPECIAL) -+ dev->type = ST_INVALID; - rc = 1; - } else if (dev->type == ST_SYSEX) { - if (c == MIDI_CMD_COMMON_SYSEX_END || diff --git a/alsa.changes b/alsa.changes index a935813..df5f1c2 100644 --- a/alsa.changes +++ b/alsa.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Oct 16 15:01:53 CEST 2007 - tiwai@suse.de + +- updated to version 1.0.15-final + * including all previous patches + ------------------------------------------------------------------- Mon Sep 17 16:04:20 CEST 2007 - tiwai@suse.de diff --git a/alsa.spec b/alsa.spec index d3accdb..bfc6b04 100644 --- a/alsa.spec +++ b/alsa.spec @@ -1,5 +1,5 @@ # -# spec file for package alsa (Version 1.0.14) +# spec file for package alsa (Version 1.0.15) # # Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -12,7 +12,7 @@ Name: alsa BuildRequires: doxygen -%define package_version 1.0.14a +%define package_version 1.0.15 License: GPL v2 or later Group: System/Libraries Requires: alsa-utils @@ -20,8 +20,8 @@ Recommends: alsa-plugins alsa-oss PreReq: %insserv_prereq %fillup_prereq AutoReqProv: on Summary: Advanced Linux Sound Architecture -Version: 1.0.14 -Release: 29 +Version: 1.0.15 +Release: 1 Source: ftp://ftp.alsa-project.org/pub/lib/alsa-lib-%{package_version}.tar.bz2 Source8: 40-alsa.rules Source11: alsasound @@ -35,10 +35,7 @@ Source21: README.testwav Source30: all_notes_off Source31: all_notes_off.bin Source32: all_notes_off.mid -Patch: alsa-lib-hg-fixes.diff -Patch1: alsa-lib-fix-use-after-free.diff -Patch2: alsa-lib-fix-input-source-as-capture.diff -Patch3: alsa-lib-fix-dmix-subdevice.diff +# Patch: alsa-lib-hg-fixes.diff Url: http://www.alsa-project.org/ BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -53,7 +50,7 @@ on your Linux box. To set it up, run yast2 or alsaconf. Authors: -------- - Jaroslav Kysela + Jaroslav Kysela Takashi Iwai %package devel @@ -72,10 +69,8 @@ to develop applications that require these. Authors: -------- - Jaroslav Kysela + Jaroslav Kysela Takashi Iwai - Abramo Bagnara - Frank van de Pol %package docs Summary: Additional Package Documentation @@ -90,10 +85,8 @@ this package's base documentation. Authors: -------- - Jaroslav Kysela + Jaroslav Kysela Takashi Iwai - Abramo Bagnara - Frank van de Pol %package -n libasound2 Summary: Advanced Linux Sound Architecture Library @@ -109,17 +102,12 @@ Architecture. Authors: -------- - Jaroslav Kysela + Jaroslav Kysela Takashi Iwai - Abramo Bagnara - Frank van de Pol %prep %setup -q -n alsa-lib-%{package_version} -%patch -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 +# %patch -p1 %{?suse_update_config:%{suse_update_config -f .}} %build @@ -259,8 +247,10 @@ exit 0 %{_libdir}/libasound.so.* %{_libdir}/alsa-lib %{_datadir}/alsa - %changelog +* Tue Oct 16 2007 - tiwai@suse.de +- updated to version 1.0.15-final + * including all previous patches * Mon Sep 17 2007 - tiwai@suse.de - fix the wrong subdevice number for dmix/dsnoop plugins (#325676) - fix the handling of "Input Source", to be as a capture element diff --git a/set_default_volume b/set_default_volume index 3fa9f04..d1d9391 100644 --- a/set_default_volume +++ b/set_default_volume @@ -31,6 +31,8 @@ set PCM 90% unmute set PCM 0dB set Synth 90% unmute set Synth 0dB +set Speaker 90% unmute +set Speaker -12dB set CD 90% unmute set CD 0dB # mute mic