]> code.delx.au - pulseaudio/commitdiff
Merge commit 'coling/master'
authorLennart Poettering <lennart@poettering.net>
Mon, 2 Mar 2009 15:28:08 +0000 (16:28 +0100)
committerLennart Poettering <lennart@poettering.net>
Mon, 2 Mar 2009 15:28:08 +0000 (16:28 +0100)
25 files changed:
Makefile.am
configure.ac
m4/shave.m4
shave-libtool.in
shave.in
src/Makefile.am
src/modules/alsa/alsa-sink.c
src/modules/alsa/alsa-source.c
src/modules/alsa/alsa-util.c
src/modules/alsa/alsa-util.h
src/modules/alsa/module-alsa-card.c
src/modules/bluetooth/bluetooth-util.c
src/modules/bluetooth/ipc.h
src/modules/bluetooth/module-bluetooth-device.c
src/modules/hal-util.c
src/modules/reserve.h
src/modules/udev-util.c [new file with mode: 0644]
src/modules/udev-util.h [new file with mode: 0644]
src/pulse/proplist.h
src/pulse/thread-mainloop.h
src/pulsecore/card.c
src/pulsecore/ffmpeg/resample2.c
src/pulsecore/sink.c
src/pulsecore/sink.h
src/pulsecore/source.c

index 8735d312be5cb4cda822b9d5203609c1fb6e72dd..9a3ca7b719d7d80a87b03460bb528eda71fa077a 100644 (file)
@@ -61,6 +61,12 @@ dist-hook:
                ( git-changelog.perl || echo "git-changelog.perl failed." ) > ${distdir}/ChangeLog 2>&1 ; \
        fi
 
+update-shave:
+       for i in shave.in shave.m4 shave-libtool.in; do \
+               wget -O $$i http://git.lespiau.name/cgit/shave/blob/\?path=shave/$$i ; \
+       done
+       mv shave.m4 m4/
+
 .PHONY: homepage distcleancheck doxygen
 
 DISTCLEANFILES = \
index a1ded9e3e47a7e93d8aa6b98151c1ea5861bcae7..77d777d76fb3c7e71d0fd49b4926aa5ff96d6dd2 100644 (file)
@@ -977,6 +977,41 @@ AC_SUBST(HAL_LIBS)
 AC_SUBST(HAVE_HAL)
 AM_CONDITIONAL([HAVE_HAL], [test "x$HAVE_HAL" = x1])
 
+#### UDEV support (optional) ####
+
+AC_ARG_ENABLE([udev],
+    AS_HELP_STRING([--disable-udev],[Disable optional UDEV support]),
+        [
+            case "${enableval}" in
+                yes) udev=yes ;;
+                no) udev=no ;;
+                *) AC_MSG_ERROR(bad value ${enableval} for --disable-udev) ;;
+            esac
+        ],
+        [udev=auto])
+if test "x${udev}" != xno -a \( "x$HAVE_OSS" = "x1" -o "x$HAVE_ALSA" = "x1" \) ; then
+    PKG_CHECK_MODULES(UDEV, [ libudev >= 137 ],
+        [
+            HAVE_UDEV=1
+            AC_DEFINE([HAVE_UDEV], 1, [Have UDEV.])
+        ],
+        [
+            HAVE_UDEV=0
+            if test "x$udev" = xyes ; then
+                AC_MSG_ERROR([*** UDEV support not found])
+            fi
+        ])
+else
+    HAVE_UDEV=0
+fi
+
+AC_SUBST(UDEV_CFLAGS)
+AC_SUBST(UDEV_LIBS)
+AC_SUBST(HAVE_UDEV)
+AM_CONDITIONAL([HAVE_UDEV], [test "x$HAVE_UDEV" = x1])
+
+AC_DEFINE([LIBUDEV_I_KNOW_THE_API_IS_SUBJECT_TO_CHANGE], 1, [I know the API is subject to change.])
+
 #### BlueZ support (optional) ####
 
 AC_ARG_ENABLE([bluez],
@@ -1340,6 +1375,11 @@ if test "x$HAVE_HAL" = "x1" ; then
    ENABLE_HAL=yes
 fi
 
+ENABLE_UDEV=no
+if test "x$HAVE_UDEV" = "x1" ; then
+   ENABLE_UDEV=yes
+fi
+
 ENABLE_TCPWRAP=no
 if test "x${LIBWRAP_LIBS}" != x ; then
    ENABLE_TCPWRAP=yes
@@ -1399,6 +1439,7 @@ echo "
     Enable Async DNS:              ${ENABLE_LIBASYNCNS}
     Enable LIRC:                   ${ENABLE_LIRC}
     Enable HAL:                    ${ENABLE_HAL}
+    Enable udev:                   ${ENABLE_UDEV}
     Enable BlueZ:                  ${ENABLE_BLUEZ}
     Enable TCP Wrappers:           ${ENABLE_TCPWRAP}
     Enable libsamplerate:          ${ENABLE_LIBSAMPLERATE}
index 44d3908b9a36e68058fd7ca9746625d2027bfbf8..0c2c9f5a0484e71024ce951c1141a584aa4d442b 100644 (file)
@@ -1,9 +1,12 @@
 dnl Make automake/libtool output more friendly to humans
 dnl
-dnl SHAVE_INIT([shavedir])
+dnl SHAVE_INIT([shavedir],[default_mode])
 dnl
 dnl shavedir: the directory where the shave scripts are, it defaults to
 dnl           $(top_builddir)
+dnl default_mode: (enable|disable) default shave mode.  This parameter
+dnl               controls shave's behaviour when no option has been
+dnl               given to configure.  It defaults to disable.
 dnl
 dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just
 dnl   before AC_CONFIG_FILE/AC_OUTPUT is perfect.  This macro rewrites CC and
@@ -11,19 +14,26 @@ dnl   LIBTOOL, you don't want the configure tests to have these variables
 dnl   re-defined.
 dnl * This macro requires GNU make's -s option.
 
-AC_DEFUN([SHAVE_INIT],
+AC_DEFUN([_SHAVE_ARG_ENABLE],
 [
-  dnl enable/disable shave
   AC_ARG_ENABLE([shave],
-    AS_HELP_STRING([--enable-shave],
-                   [use shave to make the build pretty [[default=no]]]),,
-    [enable_shave=no])
+    AS_HELP_STRING(
+      [--enable-shave],
+      [use shave to make the build pretty [[default=$1]]]),,
+      [enable_shave=$1]
+    )
+])
+
+AC_DEFUN([SHAVE_INIT],
+[
+  dnl you can tweak the default value of enable_shave
+  m4_if([$2], [enable], [_SHAVE_ARG_ENABLE(yes)], [_SHAVE_ARG_ENABLE(no)])
 
   if test x"$enable_shave" = xyes; then
     dnl where can we find the shave scripts?
     m4_if([$1],,
-      [shavedir='$(top_builddir)'],
-      [shavedir='$(top_builddir)'/$1])
+      [shavedir="$ac_pwd"],
+      [shavedir="$ac_pwd/$1"])
     AC_SUBST(shavedir)
 
     dnl make is now quiet
@@ -35,19 +45,22 @@ AC_DEFUN([SHAVE_INIT],
 
     dnl substitute libtool
     SHAVE_SAVED_LIBTOOL=$LIBTOOL
-    AC_SUBST(SHAVE_SAVED_LIBTOOL)
-    LIBTOOL="\$(SHELL) \$(shavedir)/shave-libtool '\$(SHAVE_SAVED_LIBTOOL)'"
+    LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'"
     AC_SUBST(LIBTOOL)
 
     dnl substitute cc/cxx
     SHAVE_SAVED_CC=$CC
     SHAVE_SAVED_CXX=$CXX
-    AC_SUBST(SHAVE_SAVED_CC)
-    AC_SUBST(SHAVE_SAVED_CXX)
-    CC="\$(SHELL) \$(shavedir)/shave cc '\$(SHAVE_SAVED_CC)'"
-    CXX="\$(SHELL) \$(shavedir)/shave cxx '\$(SHAVE_SAVED_CXX)'"
+    SHAVE_SAVED_FC=$FC
+    SHAVE_SAVED_F77=$F77
+    CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}"
+    CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}"
+    FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}"
+    F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}"
     AC_SUBST(CC)
     AC_SUBST(CXX)
+    AC_SUBST(FC)
+    AC_SUBST(F77)
 
     V=@
   else
@@ -58,12 +71,3 @@ AC_DEFUN([SHAVE_INIT],
   AC_SUBST(Q)
 ])
 
-AC_DEFUN([SHAVE_OUTPUT],
-[
-  if test x"$enable_shave" = xyes; then
-    dnl small workaround to fix libtool itself
-    dnl it's shokingly hard to find a better way, really! wtf...
-    test -f $srcdir/libtool && (tmpfile=`mktemp` && cat $srcdir/libtool | sed "s,^LTCC=.*$,LTCC=\"$SHELL $ac_pwd/shave cc $SHAVE_SAVED_CC\"," > $tmpfile && mv $tmpfile $srcdir/libtool)
-  fi
-
-])
index 30e6f1388883e4317ff69a61b10262f93c784171..1f3a720c1714ce0a853ad7847c9f2eb0cde68bd7 100644 (file)
@@ -8,7 +8,7 @@ fi
 
 lt_unmangle ()
 {
-   last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_]\*_la-##'`
+   last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'`
 }
 
 # the real libtool to use
index dc46ec960694dff396ad7098c04c146aaec2d843..174641e9b8f5759c5cd861ffdf0248426591d4dc 100644 (file)
--- a/shave.in
+++ b/shave.in
@@ -8,7 +8,7 @@ fi
 
 lt_unmangle ()
 {
-   last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_]\*_la-##'`
+   last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'`
 }
 
 # the tool to wrap (cc, cxx, ar, ranlib, ..)
@@ -50,6 +50,12 @@ link,*)
 *,cc)
     Q="  CC    "
     ;;
+*,fc)
+    Q="  FC    "
+    ;;
+*,f77)
+    Q="  F77   "
+    ;;
 *,*)
     # should not happen
     Q="  CC    "
index f5a1febe576a9b13cc7115bd1563fcbe9fe694f4..9f2fa02ae2d02ac843e248688cd059fe7d66b9b5 100644 (file)
@@ -1313,6 +1313,12 @@ libalsa_util_la_LIBADD += $(HAL_LIBS)
 libalsa_util_la_CFLAGS += $(HAL_CFLAGS)
 endif
 
+if HAVE_UDEV
+libalsa_util_la_SOURCES += modules/udev-util.h modules/udev-util.c
+libalsa_util_la_LIBADD += $(UDEV_LIBS)
+libalsa_util_la_CFLAGS += $(UDEV_CFLAGS)
+endif
+
 if HAVE_DBUS
 libalsa_util_la_SOURCES += modules/reserve.h modules/reserve.c modules/reserve-wrap.c modules/reserve-wrap.h
 libalsa_util_la_LIBADD += $(DBUS_LIBS) libdbus-util.la
index 708e020c2c058c025aa3d44f0c7e174987e0736d..d4325881cf408ec0e5603a95634bcc5d36db1d41 100644 (file)
@@ -1667,6 +1667,8 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
     }
 
+    pa_alsa_init_description(data.proplist);
+
     u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
     pa_sink_new_data_done(&data);
 
index 4321c7ffedb6e5fc1afe39e51b44f15ae04d7c80..7a1b0f8d8a07d90330bdfc56a182e53293e556e4 100644 (file)
@@ -1509,6 +1509,8 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_PROFILE_DESCRIPTION, profile->description);
     }
 
+    pa_alsa_init_description(data.proplist);
+
     u->source = pa_source_new(m->core, &data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
     pa_source_new_data_done(&data);
 
index 6740c06927f99ef34c85eb0c9de5fa3b882d24ec..7d833ff7a35a7327a6fbabd871894c9b7bebadc5 100644 (file)
 #include "hal-util.h"
 #endif
 
+#ifdef HAVE_UDEV
+#include "udev-util.h"
+#endif
+
 struct pa_alsa_fdlist {
     unsigned num_fds;
     struct pollfd *fds;
@@ -1362,6 +1366,26 @@ void pa_alsa_redirect_errors_dec(void) {
         snd_lib_error_set_handler(NULL);
 }
 
+pa_bool_t pa_alsa_init_description(pa_proplist *p) {
+    const char *s;
+    pa_assert(p);
+
+    if (pa_device_init_description(p))
+        return TRUE;
+
+    if ((s = pa_proplist_gets(p, "alsa.card_name"))) {
+        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s);
+        return TRUE;
+    }
+
+    if ((s = pa_proplist_gets(p, "alsa.name"))) {
+        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
 void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {
     char *cn, *lcn, *dn;
 
@@ -1385,6 +1409,10 @@ void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card) {
         pa_xfree(dn);
     }
 
+#ifdef HAVE_UDEV
+    pa_udev_get_info(c, p, card);
+#endif
+
 #ifdef HAVE_HAL
     pa_hal_get_info(c, p, card);
 #endif
@@ -1411,7 +1439,7 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *
 
     snd_pcm_class_t class;
     snd_pcm_subclass_t subclass;
-    const char *n, *id, *sdn, *cn = NULL;
+    const char *n, *id, *sdn;
     int card;
 
     pa_assert(p);
@@ -1426,6 +1454,7 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *
         if (alsa_class_table[class])
             pa_proplist_sets(p, "alsa.class", alsa_class_table[class]);
     }
+
     subclass = snd_pcm_info_get_subclass(pcm_info);
     if (subclass <= SND_PCM_SUBCLASS_LAST)
         if (alsa_subclass_table[subclass])
@@ -1443,17 +1472,8 @@ void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *
 
     pa_proplist_setf(p, "alsa.device", "%u", snd_pcm_info_get_device(pcm_info));
 
-    if ((card = snd_pcm_info_get_card(pcm_info)) >= 0) {
+    if ((card = snd_pcm_info_get_card(pcm_info)) >= 0)
         pa_alsa_init_proplist_card(c, p, card);
-        cn = pa_proplist_gets(p, "alsa.card_name");
-    }
-
-    if (cn && n && !strstr(cn, n) && !strstr(n, cn))
-        pa_proplist_setf(p, PA_PROP_DEVICE_DESCRIPTION, "%s, %s", cn, n);
-    else if (cn && (!n || strstr(cn, n)))
-        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, cn);
-    else if (n)
-        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, n);
 }
 
 void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm) {
index 899532e2498d0878f7f23c2468cc4bbe2f22378f..a8397ae9ce7575db4828effe52d5a6504dfbb6f1 100644 (file)
@@ -123,6 +123,7 @@ void pa_alsa_redirect_errors_dec(void);
 void pa_alsa_init_proplist_pcm_info(pa_core *c, pa_proplist *p, snd_pcm_info_t *pcm_info);
 void pa_alsa_init_proplist_card(pa_core *c, pa_proplist *p, int card);
 void pa_alsa_init_proplist_pcm(pa_core *c, pa_proplist *p, snd_pcm_t *pcm);
+pa_bool_t pa_alsa_init_description(pa_proplist *p);
 
 int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents);
 
index fc6b886b9d80143fbd224fc5b61b0ecd30e4aaf3..9e149a482e6369de9b52a43f4cc20825a43bf7d6 100644 (file)
@@ -318,6 +318,7 @@ int pa__init(pa_module *m) {
     data.module = m;
     pa_alsa_init_proplist_card(m->core, data.proplist, alsa_card_index);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device_id);
+    pa_alsa_init_description(data.proplist);
     set_card_name(&data, ma, u->device_id);
 
     if (reserve)
index 7855c2efdd32b3807e1d271f51a93cb77e1be2dc..6b522200a827eb30b3467b9d6c510935b864984c 100644 (file)
@@ -811,8 +811,8 @@ const char*pa_bluetooth_get_form_factor(uint32_t class) {
         [1] = "headset",
         [2] = "hands-free",
         [4] = "microphone",
-        [5] = "external-speakers",
-        [6] = "headphones",
+        [5] = "speaker",
+        [6] = "headphone",
         [7] = "portable",
         [8] = "car",
         [10] = "hifi"
index 4203150bfd82f59be8534a3234e13db6d46367d2..f030acfa24370ce0667708653e7468499326db39 100644 (file)
@@ -160,7 +160,8 @@ struct bt_get_capabilities_req {
 
 #define BT_HFP_CODEC_PCM                       0x00
 
-#define BT_PCM_FLAG_NREC                       1
+#define BT_PCM_FLAG_NREC                       0x01
+#define BT_PCM_FLAG_PCM_ROUTING                        0x02
 
 typedef struct {
        uint8_t transport;
index b2fb1db1e8d03badbac797c2ae41320810cac917..3332df2cd3a835965d8c56bcdc4dd9de1e534f80 100644 (file)
@@ -1728,7 +1728,7 @@ static int add_card(struct userdata *u, const char * default_profile) {
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->device->address);
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_API, "bluez");
     pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
-    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CONNECTOR, "bluetooth");
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_BUS, "bluetooth");
     if ((ff = pa_bluetooth_get_form_factor(u->device->class)))
         pa_proplist_sets(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, ff);
     pa_proplist_sets(data.proplist, "bluez.path", u->device->path);
index 82bbc57ee29041cf53cad7e2fc667876689955fa..6959a7062bcfe4152a550b303d6c63c60f4b01d7 100644 (file)
@@ -89,6 +89,9 @@ int pa_hal_get_info(pa_core *core, pa_proplist *p, int card) {
 
     pa_proplist_sets(p, "hal.udi", udis[i]);
 
+    /* The data HAL stores in info.product is not actually a product
+     * string but simply the ALSA card name. We will hence not write
+     * it to PA_PROP_DEVICE_PRODUCT_NAME */
     t = libhal_device_get_property_string(hal, udis[i], "info.product", &error);
     if (dbus_error_is_set(&error))
         dbus_error_free(&error);
index ceb1ad11cb480914c7fbb70399f537942dc3fece..b315a08cc69d2dcdb5835d0e89b6064340cd5051 100644 (file)
 typedef struct rd_device rd_device;
 
 /* Prototype for a function that is called whenever someone else wants
- * your app to release the device you having locked. A return value <=
- * 0 denies the request, a positive return value agrees to it. Before
- * returning your application should close the device in question
- * completely to make sure the new application may acceess it. */
+ * your application to release the device it has locked. A return
+ * value <= 0 denies the request, a positive return value agrees to
+ * it. Before returning your application should close the device in
+ * question completely to make sure the new application may access
+ * it. */
 typedef int (*rd_request_cb_t)(
        rd_device *d,
        int forced);                  /* Non-zero if an application forcibly took the lock away without asking. If this is the case then the return value of this call is ignored. */
@@ -48,20 +49,20 @@ int rd_acquire(
        const char *device_name,      /* The device to lock, e.g. "Audio0" */
        const char *application_name, /* A human readable name of the application, e.g. "PulseAudio Sound Server" */
        int32_t priority,             /* The priority for this application. If unsure use 0 */
-       rd_request_cb_t request_cb,   /* Will be called whenever someone asks that this device shall be released. May be NULL if priority is INT32_MAX */
+       rd_request_cb_t request_cb,   /* Will be called whenever someone requests that this device shall be released. May be NULL if priority is INT32_MAX */
        DBusError *error);            /* If we fail due to a D-Bus related issue the error will be filled in here. May be NULL. */
 
-/* Unlock (if needed) and destroy a rd_device object again */
+/* Unlock (if needed) and destroy an rd_device object again */
 void rd_release(rd_device *d);
 
-/* Set the application device name for a rd_device object Returns 0 on
- * success, a negative errno style return value on error. */
+/* Set the application device name for an rd_device object. Returns 0
+ * on success, a negative errno style return value on error. */
 int rd_set_application_device_name(rd_device *d, const char *name);
 
-/* Attach a userdata pointer to a rd_device */
+/* Attach a userdata pointer to an rd_device */
 void rd_set_userdata(rd_device *d, void *userdata);
 
-/* Query the userdata pointer from a rd_device. Returns NULL if no
+/* Query the userdata pointer from an rd_device. Returns NULL if no
  * userdata was set. */
 void* rd_get_userdata(rd_device *d);
 
diff --git a/src/modules/udev-util.c b/src/modules/udev-util.c
new file mode 100644 (file)
index 0000000..a72bc8f
--- /dev/null
@@ -0,0 +1,142 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Lennart Poettering
+
+  PulseAudio 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 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libudev.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/proplist.h>
+
+#include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
+
+#include "udev-util.h"
+
+static int read_id(struct udev_device *d, const char *n) {
+    const char *v;
+    unsigned u;
+
+    pa_assert(d);
+    pa_assert(n);
+
+    if (!(v = udev_device_get_property_value(d, n)))
+        return -1;
+
+    if (pa_startswith(v, "0x"))
+        v += 2;
+
+    if (!*v)
+        return -1;
+
+    if (sscanf(v, "%04x", &u) != 1)
+        return -1;
+
+    if (u > 0xFFFFU)
+        return -1;
+
+    return u;
+}
+
+int pa_udev_get_info(pa_core *core, pa_proplist *p, int card_idx) {
+    int r = -1;
+    struct udev *udev;
+    struct udev_device *card;
+    char *t;
+    const char *v;
+    int id;
+
+    pa_assert(core);
+    pa_assert(p);
+    pa_assert(card_idx >= 0);
+
+    if (!(udev = udev_new())) {
+        pa_log_error("Failed to allocate udev context.");
+        goto finish;
+    }
+
+    t = pa_sprintf_malloc("%s/class/sound/card%i", udev_get_sys_path(udev), card_idx);
+    card = udev_device_new_from_syspath(udev, t);
+    pa_xfree(t);
+
+    if (!card) {
+        pa_log_error("Failed to get card object.");
+        goto finish;
+    }
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_BUS))
+        if ((v = udev_device_get_property_value(card, "ID_BUS")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_BUS, v);
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_ID))
+        if ((id = read_id(card, "ID_VENDOR_ID")) > 0 && *v)
+            pa_proplist_setf(p, PA_PROP_DEVICE_VENDOR_ID, "%04x", id);
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_VENDOR_NAME)) {
+        if ((v = udev_device_get_property_value(card, "ID_VENDOR_FROM_DATABASE")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v);
+        else if ((v = udev_device_get_property_value(card, "ID_VENDOR")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_VENDOR_NAME, v);
+    }
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_ID))
+        if ((id = read_id(card, "ID_MODEL_ID")) >= 0)
+            pa_proplist_setf(p, PA_PROP_DEVICE_PRODUCT_ID, "%04x", id);
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_PRODUCT_NAME)) {
+        if ((v = udev_device_get_property_value(card, "ID_MODEL_FROM_DATABASE")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v);
+        else if ((v = udev_device_get_property_value(card, "ID_MODEL")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_PRODUCT_NAME, v);
+    }
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_SERIAL))
+        if ((v = udev_device_get_property_value(card, "ID_SERIAL")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_SERIAL, v);
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_FORM_FACTOR))
+        if ((v = udev_device_get_property_value(card, "SOUND_FORM_FACTOR")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_FORM_FACTOR, v);
+
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_BUS_PATH))
+        if ((v = udev_device_get_devpath(card)))
+            pa_proplist_sets(p, PA_PROP_DEVICE_BUS_PATH, v);
+
+    /* This is normaly not set by th udev rules but may be useful to
+     * allow administrators to overwrite the device description.*/
+    if (!pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
+        if ((v = udev_device_get_property_value(card, "SOUND_DESCRIPTION")) && *v)
+            pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, v);
+
+    r = 0;
+
+finish:
+
+    if (card)
+        udev_device_unref(card);
+
+    if (udev)
+        udev_unref(udev);
+
+    return r;
+}
diff --git a/src/modules/udev-util.h b/src/modules/udev-util.h
new file mode 100644 (file)
index 0000000..86fbba7
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef fooudevutilhfoo
+#define fooudevutilhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2009 Lennart Poettering
+
+  PulseAudio 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 of the
+  License, or (at your option) any later version.
+
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
+
+
+#include <pulsecore/core.h>
+
+int pa_udev_get_info(pa_core *core, pa_proplist *p, int card);
+
+#endif
index fa44c426876fd8374d50561ab8e0ad81b2ac88d7..d5f5bc0409c2149f9655ba5603184ee66755ad47 100644 (file)
@@ -45,8 +45,10 @@ PA_C_DECL_BEGIN
 /** For streams: source filename if applicable, in URI format or local path. e.g. "/home/lennart/music/foobar.ogg" */
 #define PA_PROP_MEDIA_FILENAME                 "media.filename"
 
+/** \cond fulldocs */
 /** For streams: icon for the media. A binary blob containing PNG image data */
 #define PA_PROP_MEDIA_ICON                     "media.icon"
+/** \endcond */
 
 /** For streams: an XDG icon name for the media. e.g. "audio-x-mp3" */
 #define PA_PROP_MEDIA_ICON_NAME                "media.icon_name"
@@ -81,8 +83,10 @@ PA_C_DECL_BEGIN
 /** For streams that belong to a window on the screen: a textual id for identifying a window logically. e.g. "org.gnome.Totem.MainWindow" */
 #define PA_PROP_WINDOW_ID                      "window.id"
 
+/** \cond fulldocs */
 /** For streams that belong to a window on the screen: window icon. A binary blob containing PNG image data */
 #define PA_PROP_WINDOW_ICON                    "window.icon"
+/** \endcond */
 
 /** For streams that belong to a window on the screen: an XDG icon name for the window. e.g. "totem" */
 #define PA_PROP_WINDOW_ICON_NAME               "window.icon_name"
@@ -108,8 +112,10 @@ PA_C_DECL_BEGIN
 /** For clients/streams: a version string e.g. "0.6.88" */
 #define PA_PROP_APPLICATION_VERSION            "application.version"
 
+/** \cond fulldocs */
 /** For clients/streams: application icon. A binary blob containing PNG image data */
 #define PA_PROP_APPLICATION_ICON               "application.icon"
+/** \endcond */
 
 /** For clients/streams: an XDG icon name for the application. e.g. "totem" */
 #define PA_PROP_APPLICATION_ICON_NAME          "application.icon_name"
@@ -150,17 +156,34 @@ PA_C_DECL_BEGIN
 /** For devices: serial number if applicable. e.g. "4711-0815-1234" */
 #define PA_PROP_DEVICE_SERIAL                  "device.serial"
 
-/** For devices: vendor/product ID if applicable. e.g. 1274:1371 */
-#define PA_PROP_DEVICE_VENDOR_PRODUCT_ID       "device.vendor_product_id"
+/** For devices: vendor ID if applicable. e.g. 1274 */
+#define PA_PROP_DEVICE_VENDOR_ID               "device.vendor.id"
+
+/** For devices: vendor name if applicable. e.g. "Foocorp Heavy Industries" */
+#define PA_PROP_DEVICE_VENDOR_NAME             "device.vendor.name"
+
+/** For devices: product ID if applicable. e.g. 4565 */
+#define PA_PROP_DEVICE_PRODUCT_ID              "device.product.id"
+
+/** For devices: product name if applicable. e.g. "SuperSpeakers 2000 Pro" */
+#define PA_PROP_DEVICE_PRODUCT_NAME            "device.product.name"
 
 /** For devices: device class. One of "sound", "modem", "monitor", "filter" */
 #define PA_PROP_DEVICE_CLASS                   "device.class"
 
-/** For devices: form factor if applicable. One of "internal-speakers", "external-speakers", "handset", "tv-capture", "webcam", "microphone", "headset", "headphones", "hands-free", "car", "hifi", "computer", "portable" */
+/** For devices: form factor if applicable. One of "internal", "speaker", "handset", "tv", "webcam", "microphone", "headset", "headphone", "hands-free", "car", "hifi", "computer", "portable" */
 #define PA_PROP_DEVICE_FORM_FACTOR             "device.form_factor"
 
-/** For devices: connector of the device if applicable. One of "isa", "pci", "usb", "firewire", "bluetooth" */
-#define PA_PROP_DEVICE_CONNECTOR               "device.connector"
+/** For devices: bus of the device if applicable. One of "isa", "pci", "usb", "firewire", "bluetooth" */
+#define PA_PROP_DEVICE_BUS                     "device.bus"
+
+/** \cond fulldocs */
+/** For devices: icon for the device. A binary blob containing PNG image data */
+#define PA_PROP_DEVICE_ICON                    "device.icon"
+/** \endcond */
+
+/** For devices: an XDG icon name for the device. e.g. "sound-card-speakers-usb" */
+#define PA_PROP_DEVICE_ICON_NAME               "device.icon_name"
 
 /** For devices: access mode of the device if applicable. One of "mmap", "mmap_rewrite", "serial" */
 #define PA_PROP_DEVICE_ACCESS_MODE             "device.access_mode"
index 4de338a14c3bc3cd8af623e59e045b5a48f5bab5..f0b1a84b4cdd7b3dfd4b19787fc83fe3a9dc0e72 100644 (file)
@@ -108,10 +108,10 @@ PA_C_DECL_BEGIN
  * Example:
  *
  * \code
- * static void my_drain_callback(pa_stream*s, int success, void *userdata) {
+ * static void my_drain_callback(pa_stream *s, int success, void *userdata) {
  *     pa_threaded_mainloop *m;
  *
- *     m = (pa_threaded_mainloop*)userdata;
+ *     m = userdata;
  *     assert(m);
  *
  *     pa_threaded_mainloop_signal(m, 0);
@@ -125,7 +125,7 @@ PA_C_DECL_BEGIN
  *     o = pa_stream_drain(s, my_drain_callback, m);
  *     assert(o);
  *
- *     while (pa_operation_get_state(o) != OPERATION_DONE)
+ *     while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
  *         pa_threaded_mainloop_wait(m);
  *
  *     pa_operation_unref(o);
@@ -167,7 +167,7 @@ PA_C_DECL_BEGIN
  * static void my_drain_callback(pa_stream*s, int success, void *userdata) {
  *     pa_threaded_mainloop *m;
  *
- *     m = (pa_threaded_mainloop*)userdata;
+ *     m = userdata;
  *     assert(m);
  *
  *     drain_result = &success;
@@ -183,7 +183,7 @@ PA_C_DECL_BEGIN
  *     o = pa_stream_drain(s, my_drain_callback, m);
  *     assert(o);
  *
- *     while (pa_operation_get_state(o) != OPERATION_DONE)
+ *     while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
  *         pa_threaded_mainloop_wait(m);
  *
  *     pa_operation_unref(o);
index 515d1f90881f46d6b30cd8e8bfd395de8816acb1..94064c728bf83a23e0a242245897fd2815313a23 100644 (file)
@@ -160,6 +160,9 @@ pa_card *pa_card_new(pa_core *core, pa_card_new_data *data) {
     c->userdata = NULL;
     c->set_profile = NULL;
 
+    pa_device_init_description(c->proplist);
+    pa_device_init_icon(c->proplist, TRUE);
+
     pa_assert_se(pa_idxset_put(core->cards, c, &c->index) >= 0);
 
     pa_log_info("Created %u \"%s\"", c->index, c->name);
index ed59448a49d2d3b5cf64dcf35f0cc3ca689f3a9e..ac9db73c8ca7b9cebbab097f4d776e442c433160 100644 (file)
@@ -20,7 +20,7 @@
  */
 
 /**
- * @file resample2.c
+ * @file libavcodec/resample2.c
  * audio resampling
  * @author Michael Niedermayer <michaelni@gmx.at>
  */
@@ -175,10 +175,6 @@ void av_build_filter(FELEM *filter, double factor, int tap_count, int phase_coun
 #endif
 }
 
-/**
- * Initializes an audio resampler.
- * Note, if either rate is not an integer then simply scale both rates up so they are.
- */
 AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_size, int phase_shift, int linear, double cutoff){
     AVResampleContext *c= av_mallocz(sizeof(AVResampleContext));
     double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
@@ -206,33 +202,12 @@ void av_resample_close(AVResampleContext *c){
     av_freep(&c);
 }
 
-/**
- * Compensates samplerate/timestamp drift. The compensation is done by changing
- * the resampler parameters, so no audible clicks or similar distortions occur
- * @param compensation_distance distance in output samples over which the compensation should be performed
- * @param sample_delta number of output samples which should be output less
- *
- * example: av_resample_compensate(c, 10, 500)
- * here instead of 510 samples only 500 samples would be output
- *
- * note, due to rounding the actual compensation might be slightly different,
- * especially if the compensation_distance is large and the in_rate used during init is small
- */
 void av_resample_compensate(AVResampleContext *c, int sample_delta, int compensation_distance){
 //    sample_delta += (c->ideal_dst_incr - c->dst_incr)*(int64_t)c->compensation_distance / c->ideal_dst_incr;
     c->compensation_distance= compensation_distance;
     c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
 }
 
-/**
- * resamples.
- * @param src an array of unconsumed samples
- * @param consumed the number of samples of src which have been consumed are returned here
- * @param src_size the number of unconsumed samples available
- * @param dst_size the amount of space in samples available in dst
- * @param update_ctx if this is 0 then the context wont be modified, that way several channels can be resampled with the same context
- * @return the number of samples written in dst or -1 if an error occurred
- */
 int av_resample(AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx){
     int dst_index, i;
     int index= c->index;
index 7441e9717c6608f22b9f589a0dfc016853f2c30d..fadbb8579ffbd9dc11a802964c46d5b0a7a36f2d 100644 (file)
@@ -33,6 +33,7 @@
 #include <pulse/xmalloc.h>
 #include <pulse/timeval.h>
 #include <pulse/util.h>
+#include <pulse/i18n.h>
 
 #include <pulsecore/sink-input.h>
 #include <pulsecore/namereg.h>
@@ -172,6 +173,9 @@ pa_sink* pa_sink_new(
     if (data->card)
         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
 
+    pa_device_init_description(data->proplist);
+    pa_device_init_icon(data->proplist, TRUE);
+
     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SINK_FIXATE], data) < 0) {
         pa_xfree(s);
         pa_namereg_unregister(core, name);
@@ -1886,3 +1890,68 @@ size_t pa_sink_get_max_request(pa_sink *s) {
 
     return r;
 }
+
+/* Called from main context */
+pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink) {
+    const char *ff, *t = NULL, *s = "", *profile, *bus;
+
+    pa_assert(p);
+
+    if (pa_proplist_contains(p, PA_PROP_DEVICE_ICON_NAME))
+        return TRUE;
+
+    if ((ff = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR))) {
+
+        if (pa_streq(ff, "microphone"))
+            t = "audio-input-microphone";
+        else if (pa_streq(ff, "webcam"))
+            t = "camera-web";
+        else if (pa_streq(ff, "computer"))
+            t = "computer";
+        else if (pa_streq(ff, "handset"))
+            t = "phone";
+    }
+
+    if (!t) {
+        if (is_sink)
+            t = "audio-card";
+        else
+            t = "audio-input-microphone";
+    }
+
+    if ((profile = pa_proplist_gets(p, PA_PROP_DEVICE_PROFILE_NAME))) {
+        if (strstr(profile, "analog"))
+            s = "-analog";
+        else if (strstr(profile, "iec958"))
+            s = "-iec958";
+        else if (strstr(profile, "hdmi"))
+            s = "-hdmi";
+    }
+
+    bus = pa_proplist_gets(p, PA_PROP_DEVICE_BUS);
+
+    pa_proplist_setf(p, PA_PROP_DEVICE_ICON_NAME, "%s%s%s%s", t, pa_strempty(s), bus ? "-" : "", pa_strempty(bus));
+
+    return TRUE;
+}
+
+pa_bool_t pa_device_init_description(pa_proplist *p) {
+    const char *s;
+    pa_assert(p);
+
+    if (pa_proplist_contains(p, PA_PROP_DEVICE_DESCRIPTION))
+        return TRUE;
+
+    if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_FORM_FACTOR)))
+        if (pa_streq(s, "internal")) {
+            pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, _("Internal Audio"));
+            return TRUE;
+        }
+
+    if ((s = pa_proplist_gets(p, PA_PROP_DEVICE_PRODUCT_NAME))) {
+        pa_proplist_sets(p, PA_PROP_DEVICE_DESCRIPTION, s);
+        return TRUE;
+    }
+
+    return FALSE;
+}
index 124b4e11b5567a3b24617fa4bfbae0832edce3a4..2eaae6973901fe2b7befd0b9b36a4922b68b50bb 100644 (file)
@@ -225,6 +225,9 @@ void pa_sink_attach(pa_sink *s);
 
 void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume);
 
+pa_bool_t pa_device_init_description(pa_proplist *p);
+pa_bool_t pa_device_init_icon(pa_proplist *p, pa_bool_t is_sink);
+
 /**** May be called by everyone, from main context */
 
 /* The returned value is supposed to be in the time domain of the sound card! */
index c0d6d9ea3318589186e4c31d36502d4c6434e2ee..4ce5cbfe524200fe565997465c7f9a22cae8abfb 100644 (file)
@@ -163,6 +163,9 @@ pa_source* pa_source_new(
     if (data->card)
         pa_proplist_update(data->proplist, PA_UPDATE_MERGE, data->card->proplist);
 
+    pa_device_init_description(data->proplist);
+    pa_device_init_icon(data->proplist, FALSE);
+
     if (pa_hook_fire(&core->hooks[PA_CORE_HOOK_SOURCE_FIXATE], data) < 0) {
         pa_xfree(s);
         pa_namereg_unregister(core, name);