]> code.delx.au - pulseaudio/commitdiff
Merge commit 'origin/master-tx' into master-tx
authorLennart Poettering <lennart@poettering.net>
Tue, 7 Oct 2008 19:38:06 +0000 (21:38 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 7 Oct 2008 19:38:06 +0000 (21:38 +0200)
Conflicts:
po/de.po

94 files changed:
configure.ac
man/pulse-client.conf.5.xml.in
man/pulse-daemon.conf.5.xml.in
man/pulseaudio.1.xml.in
po/POTFILES.in
po/de.po
po/el.po
po/fr.po
po/pl.po
po/pt_BR.po
po/sv.po
src/.gitignore
src/Makefile.am
src/daemon/caps.c
src/daemon/daemon-conf.c
src/daemon/daemon-conf.h
src/daemon/daemon.conf.in
src/daemon/default.pa.in
src/daemon/main.c
src/daemon/system.pa.in
src/map-file
src/modules/alsa-util.c
src/modules/alsa-util.h
src/modules/bluetooth/Makefile [new symlink]
src/modules/bluetooth/ipc.c [new file with mode: 0644]
src/modules/bluetooth/ipc.h [new file with mode: 0644]
src/modules/bluetooth/module-bluetooth-device.c [new file with mode: 0644]
src/modules/bluetooth/module-bluetooth-discover.c [new file with mode: 0644]
src/modules/bluetooth/module-bluetooth-proximity.c [moved from src/modules/module-bt-proximity.c with 99% similarity]
src/modules/bluetooth/proximity-helper.c [moved from src/modules/bt-proximity-helper.c with 100% similarity]
src/modules/bluetooth/rtp.h [new file with mode: 0644]
src/modules/bluetooth/sbc.c [new file with mode: 0644]
src/modules/bluetooth/sbc.h [new file with mode: 0644]
src/modules/bluetooth/sbc_math.h [new file with mode: 0644]
src/modules/bluetooth/sbc_tables.h [new file with mode: 0644]
src/modules/gconf/Makefile [changed from file to symlink]
src/modules/gconf/module-gconf.c
src/modules/module-alsa-sink.c
src/modules/module-alsa-source.c
src/modules/module-null-sink.c
src/modules/module-protocol-stub.c
src/modules/module-suspend-on-idle.c
src/modules/module-tunnel.c
src/modules/rtp/Makefile [changed from file to symlink]
src/modules/rtp/module-rtp-recv.c
src/pulse/channelmap.c
src/pulse/channelmap.h
src/pulse/client-conf.c
src/pulse/client-conf.h
src/pulse/client.conf.in
src/pulse/context.c
src/pulse/introspect.c
src/pulse/sample.c
src/pulse/sample.h
src/pulse/stream.c
src/pulse/volume.c
src/pulse/volume.h
src/pulsecore/conf-parser.c
src/pulsecore/conf-parser.h
src/pulsecore/core-scache.c
src/pulsecore/core-util.c
src/pulsecore/core-util.h
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/flist.h
src/pulsecore/idxset.c
src/pulsecore/log.c
src/pulsecore/macro.h
src/pulsecore/memblock.c
src/pulsecore/memblock.h
src/pulsecore/namereg.c
src/pulsecore/namereg.h
src/pulsecore/prioq.c [new file with mode: 0644]
src/pulsecore/prioq.h [new file with mode: 0644]
src/pulsecore/proplist-util.c
src/pulsecore/protocol-native.c
src/pulsecore/protocol-simple.c
src/pulsecore/sample-util.c
src/pulsecore/sconv-s16le.c
src/pulsecore/sconv.c
src/pulsecore/sink-input.c
src/pulsecore/sink.c
src/pulsecore/thread.h
src/pulsecore/time-smoother.c
src/tests/envelope-test.c
src/tests/mcalign-test.c
src/tests/memblock-test.c
src/tests/memblockq-test.c
src/tests/mix-test.c
src/tests/prioq-test.c [new file with mode: 0644]
src/tests/remix-test.c
src/tests/resampler-test.c
src/tests/voltest.c
src/utils/padsp.c

index 3c3550fbfc9839b7fbd62963db4b9fa34899730b..2b91a0064008fd5dca29b5a6b619a6746d6cc1b3 100644 (file)
@@ -24,7 +24,7 @@ AC_PREREQ(2.62)
 
 m4_define(PA_MAJOR, [0])
 m4_define(PA_MINOR, [9])
-m4_define(PA_MICRO, [12])
+m4_define(PA_MICRO, [13])
 
 AC_INIT([pulseaudio],[PA_MAJOR.PA_MINOR.PA_MICRO],[mzchyfrnhqvb (at) 0pointer (dot) net])
 AC_CONFIG_SRCDIR([src/daemon/main.c])
@@ -40,7 +40,7 @@ AC_SUBST(PA_PROTOCOL_VERSION, 14)
 
 # The stable ABI for client applications, for the version info x:y:z
 # always will hold y=z
-AC_SUBST(LIBPULSE_VERSION_INFO, [6:0:6])
+AC_SUBST(LIBPULSE_VERSION_INFO, [7:0:7])
 
 # A simplified, synchronous, ABI-stable interface for client
 # applications, for the version info x:y:z always will hold y=z
@@ -57,7 +57,7 @@ AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:4:0])
 # An internally used, ABI-unstable library that contains the
 # PulseAudio core, SONAMEs are bumped on every release, version info
 # suffix will always be 0:0
-AC_SUBST(LIBPULSECORE_VERSION_INFO, [7:0:0])
+AC_SUBST(LIBPULSECORE_VERSION_INFO, [8:0:0])
 
 AC_CANONICAL_HOST
 AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
index ae8de1f80a23026212b09d3348177a95d38f45d4..26e389081a797040b3814673e2f3c0315df3e9d8 100644 (file)
@@ -31,15 +31,15 @@ USA.
 
   <description>
     <p>The PulseAudio client library reads configuration directives from
-    a file <file>~/.pulse/client.conf</file> on startup, and when that
+    a file <file>~/.pulse/client.conf</file> on startup and when that
     file doesn't exist from
     <file>@pulseconfdir@/client.conf</file>.</p>
 
     <p>The configuration file is a simple collection of variable
     declarations. If the configuration file parser encounters either ;
-    or # for it ignores the rest of the line until its end.</p>
+    or # it ignores the rest of the line until its end.</p>
 
-    <p>For the settings that take a boolean argument, the values
+    <p>For the settings that take a boolean argument the values
     <opt>true</opt>, <opt>yes</opt>, <opt>on</opt> and <opt>1</opt>
     are equivalent, resp. <opt>false</opt>, <opt>no</opt>,
     <opt>off</opt>, <opt>0</opt>.</p>
@@ -69,7 +69,7 @@ USA.
 
     <option>
       <p><opt>autospawn=</opt> Autospawn a PulseAudio daemon when
-      needed. Takes a boolean value, defaults to "no".</p>
+      needed. Takes a boolean value, defaults to "yes".</p>
     </option>
 
     <option>
@@ -81,7 +81,7 @@ USA.
     <option>
       <p><opt>extra-arguments=</opt> Extra arguments to pass to the
       PulseAudio daemon when autospawning. Defaults to
-      <opt>--log-target=syslog --exit-idle-time=5</opt>
+      <opt>--log-target=syslog</opt>
       </p>
     </option>
 
@@ -97,6 +97,15 @@ USA.
       <opt>no</opt>.</p>
     </option>
 
+    <option>
+      <p><opt>shm-size-bytes=</opt> Sets the shared memory segment
+      size for clients, in bytes. If left unspecified or is set to 0
+      it will default to some system-specific default, usually 64
+      MiB. Please note that usually there is no need to change this
+      value, unless you are running an OS kernel that does not do
+      memory overcommit.</p>
+    </option>
+
   </section>
 
   <section name="Authors">
index ed158dfa06ee024e9ae87da83a7b272e0185eab9..a516ee3f3c40d8669306e66a427af7bf5e33f734 100644 (file)
@@ -31,7 +31,7 @@ USA.
 
   <description>
     <p>The PulseAudio sound server reads configuration directives from
-    a file <file>~/.pulse/daemon.conf</file> on startup, and when that
+    a file <file>~/.pulse/daemon.conf</file> on startup and when that
     file doesn't exist from
     <file>@pulseconfdir@/daemon.conf</file>. Please note that the
     server also reads a configuration script on startup
@@ -40,9 +40,9 @@ USA.
 
     <p>The configuration file is a simple collection of variable
     declarations. If the configuration file parser encounters either ;
-    or # for it ignores the rest of the line until its end.</p>
+    or # it ignores the rest of the line until its end.</p>
 
-    <p>For the settings that take a boolean argument, the values
+    <p>For the settings that take a boolean argument the values
     <opt>true</opt>, <opt>yes</opt>, <opt>on</opt> and <opt>1</opt>
     are equivalent, resp. <opt>false</opt>, <opt>no</opt>,
     <opt>off</opt>, <opt>0</opt>.</p>
@@ -76,6 +76,11 @@ USA.
       option takes precedence.</p>
     </option>
 
+    <option>
+      <p><opt>disallow-exit=</opt> Disallow exit on user
+      request. Defaults to <opt>no</opt>.</p>
+    </option>
+
     <option>
       <p><opt>resample-method=</opt> The resampling algorithm to
       use. Use one of <opt>src-sinc-best-quality</opt>,
@@ -112,7 +117,7 @@ USA.
       available as well. If no input LFE channel is available the
       output LFE channel will always be 0. If no output LFE channel is
       available the signal on the input LFE channel will be
-      ignored.</p>
+      ignored. Defaults to "on".</p>
     </option>
 
     <option>
@@ -151,6 +156,15 @@ USA.
       argument takes precedence.</p>
     </option>
 
+    <option>
+      <p><opt>shm-size-bytes=</opt> Sets the shared memory segment
+      size for the daemon, in bytes. If left unspecified or is set to 0
+      it will default to some system-specific default, usually 64
+      MiB. Please note that usually there is no need to change this
+      value, unless you are running an OS kernel that does not do
+      memory overcommit.</p>
+    </option>
+
   </section>
 
   <section name="Scheduling">
@@ -240,9 +254,17 @@ USA.
       default script file. The default behaviour is to load
       <file>~/.pulse/default.pa</file>, and if that file does not
       exist fall back to the system wide installed version
-      <file>@pulseconfdir@/default.pa</file>. If <opt>-n</opt> is
-      passed on the command line the default configuration script is
-      ignored.</p>
+      <file>@pulseconfdir@/default.pa</file>. If run in system-wide
+      mode the file <file>@pulseconfdir@/system.pa</file> is used
+      instead. If <opt>-n</opt> is passed on the command line
+      or <opt>default-script-file=</opt> is disabled the default
+      configuration script is ignored.</p>
+    </option>
+
+    <option>
+      <p><opt>default-script-file=</opt> Load the default
+      configuration script file as specified
+      in <opt>default-script-file=</opt>. Defaults to "yes".</p>
     </option>
 
   </section>
@@ -281,6 +303,9 @@ USA.
     <option>
       <p><opt>rlimit-as</opt> Defaults to -1.</p>
     </option>
+    <option>
+      <p><opt>rlimit-rss</opt> Defaults to -1.</p>
+    </option>
     <option>
       <p><opt>rlimit-core</opt> Defaults to -1.</p>
     </option>
@@ -299,6 +324,15 @@ USA.
     <option>
       <p><opt>rlimit-nproc</opt> Defaults to -1.</p>
     </option>
+    <option>
+      <p><opt>rlimit-locks</opt> Defaults to -1.</p>
+    </option>
+    <option>
+      <p><opt>rlimit-sigpending</opt> Defaults to -1.</p>
+    </option>
+    <option>
+      <p><opt>rlimit-msgqueue</opt> Defaults to -1.</p>
+    </option>
     <option>
       <p><opt>rlimit-memlock</opt> Defaults to 16 KiB. Please note
       that the JACK client libraries may require more locked
@@ -317,6 +351,9 @@ USA.
       <opt>realtime-scheduling</opt> is enabled. The JACK client
       libraries require a real-time prority of 9 by default. </p>
     </option>
+    <option>
+      <p><opt>rlimit-rttime</opt> Defaults to 1000000.</p>
+    </option>
 
   </section>
 
index 0e008c3db89e785a8929031bfcbbff1a7e2c70a9..df828242b29b6812e74cbb158f6779b83c13d423 100644 (file)
@@ -127,7 +127,7 @@ USA.
     </option>
 
     <option>
-      <p><opt>-D | --daemon</opt><arg>[=BOOL]</arg></p>
+      <p><opt>-D | --daemonize</opt><arg>[=BOOL]</arg></p>
 
       <optdesc><p>Daemonize after startup, i.e. detach from the
       terminal.</p></optdesc>
index 6efb1d089d590fcbb4a3cbf0d6c47ee0f33852ec..c20340eab214d3395433ff1255c72ae3121f5b74 100644 (file)
@@ -17,7 +17,7 @@ src/modules/module-solaris.c
 src/modules/module-default-device-restore.c
 src/modules/module-x11-xsmp.c
 src/modules/module-remap-sink.c
-src/modules/module-bt-proximity.c
+src/modules/bluetooth/module-bluetooth-proximity.c
 src/modules/module-detect.c
 src/modules/module-always-sink.c
 src/modules/module-lirc.c
@@ -39,7 +39,7 @@ src/modules/module-esound-compat-spawnfd.c
 src/modules/module-esound-compat-spawnpid.c
 #src/modules/module-waveout.c
 src/modules/module-combine.c
-src/modules/bt-proximity-helper.c
+src/modules/bluetooth/proximity-helper.c
 src/modules/module-x11-publish.c
 src/modules/rtp/module-rtp-recv.c
 src/modules/rtp/sdp.c
index 4fc870689432aac7eab9209679eb312e0ebc1b8e..b587e21cce86e4c3bf429eccb7208878498cf8ad 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -7,9 +7,9 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-11 19:30+0000\n"
-"PO-Revision-Date: 2008-09-29 12:57+0100\n"
-"Last-Translator: Fabian Affolter <fab@fedoraproject.org>\n"
+"POT-Creation-Date: 2008-10-07 21:03+0200\n"
+"PO-Revision-Date: 2008-10-07 21:36+0100\n"
+"Last-Translator: Lennart Poettering <lennart@poettering.net>\n"
 "Language-Team: German <fedora-trans-de@redhat.com>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=utf-8\n"
@@ -17,10 +17,9 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Poedit-Language: German\n"
 
-#: ../src/daemon/ltdl-bind-now.c:177
-#: ../src/daemon/ltdl-bind-now.c:197
+#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
 msgid "Failed to add bind-now-loader."
-msgstr "Hinzufügen von bind-now-loader fehlgeschlagen."
+msgstr "Hinzufügen von Bind-Now-Loader fehlgeschlagen."
 
 #: ../src/daemon/ltdl-bind-now.c:184
 msgid "Failed to find original dlopen loader."
@@ -34,11 +33,11 @@ msgstr "Kann nicht mit dem System-Bus verbinden: %s"
 #: ../src/daemon/polkit.c:65
 #, c-format
 msgid "Cannot get caller from PID: %s"
-msgstr "Kann caller von PID nicht benziehen: %s"
+msgstr "Kann Caller von PID nicht beziehen: %s"
 
 #: ../src/daemon/polkit.c:77
 msgid "Cannot set UID on caller object."
-msgstr "Kann caller-Ojekt für UID nicht setzen."
+msgstr "Kann Caller-Ojekt für UID nicht setzen."
 
 #: ../src/daemon/polkit.c:82
 msgid "Failed to get CK session."
@@ -49,23 +48,21 @@ msgid "Cannot set UID on session object."
 msgstr "Kann UID auf Session-Objekt nicht setzen."
 
 #: ../src/daemon/polkit.c:95
-#, fuzzy
 msgid "Cannot allocate PolKitAction."
-msgstr "Farbtabelleneinträge konnten nicht bereitgestellt werden"
+msgstr "Konnte PolKitAction nicht allozieren."
 
 #: ../src/daemon/polkit.c:100
 msgid "Cannot set action_id"
 msgstr "Kann action_id nicht setzen"
 
 #: ../src/daemon/polkit.c:105
-#, fuzzy
 msgid "Cannot allocate PolKitContext."
-msgstr "Farbtabelleneinträge konnten nicht bereitgestellt werden"
+msgstr "Konnte PolKitContext nicht allozieren"
 
 #: ../src/daemon/polkit.c:110
-#, fuzzy, c-format
+#, c-format
 msgid "Cannot initialize PolKitContext: %s"
-msgstr "Kann OLE nicht initialisieren"
+msgstr "Konnte PolKitContect nicht initialisieren: %s"
 
 #: ../src/daemon/polkit.c:119
 #, c-format
@@ -73,9 +70,9 @@ msgid "Could not determine whether caller is authorized: %s"
 msgstr ""
 
 #: ../src/daemon/polkit.c:139
-#, fuzzy, c-format
+#, c-format
 msgid "Cannot obtain auth: %s"
-msgstr "Kann die Datei nicht bearbeiten"
+msgstr "Erhalten der Authorisierung fehlgeschlagen: %s"
 
 #: ../src/daemon/polkit.c:148
 #, c-format
@@ -116,8 +113,7 @@ msgstr "GID von Benutzer '%s' und von Gruppe '%s' stimme nicht überein."
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Benutzerverzeichnis von Benutzer '%s' ist nicht '%s', ignoriere."
 
-#: ../src/daemon/main.c:201
-#: ../src/daemon/main.c:206
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Erzeugen von '%s' fehlgeschlagen: %s"
@@ -130,7 +126,7 @@ msgstr "Wechseln der Gruppen-Liste fehlgeschlagen: %s"
 #: ../src/daemon/main.c:229
 #, c-format
 msgid "Failed to change GID: %s"
-msgstr "WEchseln der GID fehlgeschlagen: %s"
+msgstr "Wechseln der GID fehlgeschlagen: %s"
 
 #: ../src/daemon/main.c:245
 #, c-format
@@ -143,7 +139,7 @@ msgstr "Root-Berechtigungen erfolgreich zurückgesetzt."
 
 #: ../src/daemon/main.c:267
 msgid "System wide mode unsupported on this platform."
-msgstr "Systemweiter Modus auf dieser Plattform nicht unterstützt."
+msgstr "System-Modus auf dieser Plattform nicht unterstützt."
 
 #: ../src/daemon/main.c:285
 #, c-format
@@ -151,9 +147,8 @@ msgid "setrlimit(%s, (%u, %u)) failed: %s"
 msgstr "setrlimit(%s, (%u, %u)) fehlgeschlagen: %s"
 
 #: ../src/daemon/main.c:425
-#, fuzzy
 msgid "Failed to parse command line."
-msgstr "Parsen der Port-Nummer fehlgeschlagen: %s\n"
+msgstr "Parsen der Kommandzeile fehlgeschlagen."
 
 #: ../src/daemon/main.c:441
 #, c-format
@@ -183,22 +178,14 @@ msgstr ""
 
 #: ../src/daemon/main.c:479
 msgid ""
-"Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
+"Called SUID root and real-time/high-priority scheduling was requested in the "
+"configuration. However, we lack the necessary priviliges:\n"
 "We are not in group '"
 msgstr ""
 
-#: ../src/daemon/main.c:480
-msgid ""
-"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
-"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"
-msgstr ""
-
-#: ../src/daemon/main.c:481
-msgid "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
-msgstr ""
-
 #: ../src/daemon/main.c:497
-msgid "High-priority scheduling enabled in configuration but not allowed by policy."
+msgid ""
+"High-priority scheduling enabled in configuration but not allowed by policy."
 msgstr ""
 
 #: ../src/daemon/main.c:522
@@ -215,7 +202,8 @@ msgid "Giving up CAP_NICE"
 msgstr "Gebe CAP_NICE auf"
 
 #: ../src/daemon/main.c:539
-msgid "Real-time scheduling enabled in configuration but not allowed by policy."
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
 msgstr ""
 
 #: ../src/daemon/main.c:597
@@ -225,15 +213,17 @@ msgstr "Daemon läuft nicht"
 #: ../src/daemon/main.c:599
 #, c-format
 msgid "Daemon running as PID %u"
-msgstr "Lasse Daemon als PID %u laufen"
+msgstr "Daemon läuft als PID %u"
 
 #: ../src/daemon/main.c:609
-#, fuzzy, c-format
+#, c-format
 msgid "Failed to kill daemon: %s"
-msgstr "Konnte Prozess %d nicht abbrechen"
+msgstr "Konnte Prozess nicht abbrechen: %s"
 
 #: ../src/daemon/main.c:627
-msgid "This program is not intended to be run as root (unless --system is specified)."
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
 msgstr ""
 
 #: ../src/daemon/main.c:629
@@ -241,7 +231,6 @@ msgid "Root priviliges required."
 msgstr "Root-Berechtigungen benötigt."
 
 #: ../src/daemon/main.c:634
-#, fuzzy
 msgid "--start not supported for system instances."
 msgstr "--start nicht unterstützt für System-Instanzen."
 
@@ -262,9 +251,8 @@ msgid "Running in system mode, forcibly disabling exit idle time!"
 msgstr ""
 
 #: ../src/daemon/main.c:677
-#, fuzzy
 msgid "Failed to acquire stdio."
-msgstr "Verzeichnis konnte nicht gewechselt werden"
+msgstr "Reservieren von STDIO fehlgeschlagen."
 
 #: ../src/daemon/main.c:683
 #, c-format
@@ -295,14 +283,14 @@ msgid "This is PulseAudio %s"
 msgstr "Dies ist PulseAudio %s"
 
 #: ../src/daemon/main.c:781
-#, fuzzy, c-format
+#, c-format
 msgid "Compilation host: %s"
 msgstr "Kompilations-Host: %s"
 
 #: ../src/daemon/main.c:782
 #, c-format
 msgid "Compilation CFLAGS: %s"
-msgstr "KompilierCFLAGS: %s"
+msgstr "Kompilier-CFLAGS: %s"
 
 #: ../src/daemon/main.c:785
 #, c-format
@@ -322,77 +310,83 @@ msgstr "Kompiliere mit Valgrind-Unterstützung: ja"
 msgid "Compiled with Valgrind support: no"
 msgstr "Kompiliere mit Valgrind-Unterstützung: nein"
 
-#: ../src/daemon/main.c:797
+#: ../src/daemon/main.c:796
+#, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "Laufe im Valgrind-Modus: %s"
+
+#: ../src/daemon/main.c:799
 msgid "Optimized build: yes"
 msgstr "Optimiertes Build: ja"
 
-#: ../src/daemon/main.c:799
+#: ../src/daemon/main.c:801
 msgid "Optimized build: no"
 msgstr "Optimiertes Build: nein"
 
-#: ../src/daemon/main.c:803
+#: ../src/daemon/main.c:805
 msgid "Failed to get machine ID"
-msgstr "Erhalten der Maschinen-ID fehlgeschlagen"
+msgstr "Beziehen der Maschinen-ID fehlgeschlagen"
 
-#: ../src/daemon/main.c:806
+#: ../src/daemon/main.c:808
 #, c-format
 msgid "Machine ID is %s."
 msgstr "System- ID ist %s."
 
-#: ../src/daemon/main.c:811
-#, fuzzy, c-format
+#: ../src/daemon/main.c:813
+#, c-format
 msgid "Using runtime directory %s."
-msgstr "&Lokaler Verzeichnisbaum"
+msgstr "Nutze Laufzeit-Verzeichnis %s."
 
-#: ../src/daemon/main.c:816
-#, fuzzy, c-format
+#: ../src/daemon/main.c:818
+#, c-format
 msgid "Using state directory %s."
-msgstr "&Lokaler Verzeichnisbaum"
+msgstr "Nutze Zustands-Verzeichnis %s."
 
-#: ../src/daemon/main.c:819
-#, fuzzy, c-format
+#: ../src/daemon/main.c:821
+#, c-format
 msgid "Running in system mode: %s"
-msgstr "Standard-Enforcing-Modus des Systems"
+msgstr "Laufe im System-Modus: %s"
 
-#: ../src/daemon/main.c:834
+#: ../src/daemon/main.c:836
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() fehlgeschlagen."
 
-#: ../src/daemon/main.c:846
+#: ../src/daemon/main.c:848
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 
-#: ../src/daemon/main.c:848
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
+#: ../src/daemon/main.c:850
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
 msgstr ""
 
-#: ../src/daemon/main.c:858
+#: ../src/daemon/main.c:860
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() fehlgeschlagen."
 
-#: ../src/daemon/main.c:919
-#, fuzzy
+#: ../src/daemon/main.c:921
 msgid "Failed to initialize daemon."
-msgstr "TLS konnte nicht initialisiert werden."
+msgstr "Konnte Dämon nicht initialisieren"
 
-#: ../src/daemon/main.c:924
+#: ../src/daemon/main.c:926
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:929
+#: ../src/daemon/main.c:931
 #, c-format
 msgid "Default sink name (%s) does not exist in name register."
 msgstr ""
 
-#: ../src/daemon/main.c:942
+#: ../src/daemon/main.c:944
 msgid "Daemon startup complete."
 msgstr "Start des Dämons abgeschlossen."
 
-#: ../src/daemon/main.c:948
+#: ../src/daemon/main.c:950
 msgid "Daemon shutdown initiated."
 msgstr "Herunterfahren des Daemon gestartet."
 
-#: ../src/daemon/main.c:969
+#: ../src/daemon/main.c:971
 msgid "Daemon terminated."
 msgstr "Dämon beendet."
 
@@ -407,8 +401,10 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
 "      --check                           Check for a running daemon\n"
 "\n"
@@ -417,24 +413,31 @@ msgid ""
 "  -D, --daemonize[=BOOL]                Daemonize after startup\n"
 "      --fail[=BOOL]                     Quit when startup fails\n"
 "      --high-priority[=BOOL]            Try to set high nice level\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -445,10 +448,12 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -461,8 +466,10 @@ msgstr ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
 "      --check                           Check for a running daemon\n"
 "\n"
@@ -471,24 +478,31 @@ msgstr ""
 "  -D, --daemonize[=BOOL]                Daemonize after startup\n"
 "      --fail[=BOOL]                     Quit when startup fails\n"
 "      --high-priority[=BOOL]            Try to set high nice level\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -499,10 +513,12 @@ msgstr ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -516,7 +532,9 @@ msgid "--fail expects boolean argument"
 msgstr ""
 
 #: ../src/daemon/cmdline.c:262
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
 msgstr ""
 
 #: ../src/daemon/cmdline.c:274
@@ -541,7 +559,8 @@ msgstr ""
 
 #: ../src/daemon/cmdline.c:319
 msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
-msgstr "Ungültiges Log-Ziel: Benutzen Sie entweder 'syslog', 'stderr' oder 'auto'."
+msgstr ""
+"Ungültiges Log-Ziel: Benutzen Sie entweder 'syslog', 'stderr' oder 'auto'."
 
 #: ../src/daemon/cmdline.c:338
 #, c-format
@@ -600,76 +619,76 @@ msgstr "Lade einmalig: %s\n"
 msgid "Path: %s\n"
 msgstr "Pfad: %s\n"
 
-#: ../src/daemon/daemon-conf.c:204
+#: ../src/daemon/daemon-conf.c:205
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Ungültiges Log-Ziel '%s'."
 
-#: ../src/daemon/daemon-conf.c:220
+#: ../src/daemon/daemon-conf.c:221
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Ungültige Log-Stufe '%s'."
 
-#: ../src/daemon/daemon-conf.c:236
+#: ../src/daemon/daemon-conf.c:237
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Ungültige Resample-Methode '%s'."
 
-#: ../src/daemon/daemon-conf.c:259
+#: ../src/daemon/daemon-conf.c:260
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Ungültiges rlimit '%s'."
 
-#: ../src/daemon/daemon-conf.c:266
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr "[%s:%u] rlimit nicht unterstützt auf dieser Plattform."
 
-#: ../src/daemon/daemon-conf.c:282
+#: ../src/daemon/daemon-conf.c:283
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Ungültiges Sample-Format '%s'."
 
-#: ../src/daemon/daemon-conf.c:300
+#: ../src/daemon/daemon-conf.c:301
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Ungültige Sample-Rate '%s'."
 
-#: ../src/daemon/daemon-conf.c:318
+#: ../src/daemon/daemon-conf.c:319
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Ungültige Sample-Kanäle '%s'."
 
-#: ../src/daemon/daemon-conf.c:336
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Ungültige Anzahl von Fragmenten '%s'."
 
-#: ../src/daemon/daemon-conf.c:354
+#: ../src/daemon/daemon-conf.c:355
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
-msgstr "[%s:%u] Ungültige Fragement-Grösse '%s'."
+msgstr "[%s:%u] Ungültige Fragment-Größe '%s'."
 
-#: ../src/daemon/daemon-conf.c:372
+#: ../src/daemon/daemon-conf.c:373
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Ungültige Nice-Stufe '%s'."
 
-#: ../src/daemon/daemon-conf.c:567
+#: ../src/daemon/daemon-conf.c:570
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Öffnen der Konfigurationsdatei fehlgeschlagen : %s"
 
-#: ../src/daemon/daemon-conf.c:641
+#: ../src/daemon/daemon-conf.c:644
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lesen von Konfigurationsdatei: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
 msgid "Dropping root priviliges."
-msgstr "Verlasse Root-Berechtigungen."
+msgstr "Gebe Root-Privilegien auf."
 
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
@@ -855,7 +874,7 @@ msgstr "Oben Mitte"
 
 #: ../src/pulse/channelmap.c:155
 msgid "Top Front Center"
-msgstr "Oben Vorne Mitter"
+msgstr "Oben Vorne Mitte"
 
 #: ../src/pulse/channelmap.c:156
 msgid "Top Front Left"
@@ -877,6 +896,11 @@ msgstr "Oben Hinten Links"
 msgid "Top Rear Right"
 msgstr "Oben Hinten Rechts"
 
+#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
+#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+msgid "(invalid)"
+msgstr "(ungültig)"
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr "OK"
@@ -899,7 +923,7 @@ msgstr "Entität existiert bereits"
 
 #: ../src/pulse/error.c:48
 msgid "No such entity"
-msgstr "Keine Entität vorhanden"
+msgstr "Entität nicht vorhanden"
 
 #: ../src/pulse/error.c:49
 msgid "Connection refused"
@@ -927,7 +951,7 @@ msgstr "Verbindung beendet"
 
 #: ../src/pulse/error.c:55
 msgid "Entity killed"
-msgstr "Entität terminiert."
+msgstr "Entität terminiert"
 
 #: ../src/pulse/error.c:56
 msgid "Invalid server"
@@ -965,24 +989,18 @@ msgstr "Unbekannter Fehlercode"
 msgid "No such extension"
 msgstr "Erweiterung nicht vorhanden"
 
-#: ../src/pulse/sample.c:134
-msgid "Invalid"
-msgstr "Ungültig"
-
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() fehlgeschlagen"
 
 #: ../src/pulse/client-conf-x11.c:78
-#, fuzzy
 msgid "Failed to parse cookie data"
-msgstr "TIFF-Daten konnten nicht gespeichert werden"
+msgstr "Parsen der Cookie-Daten fehlgeschlagen"
 
-#: ../src/pulse/client-conf.c:117
-#, fuzzy, c-format
+#: ../src/pulse/client-conf.c:120
+#, c-format
 msgid "Failed to open configuration file '%s': %s"
-msgstr "Datei »%s« konnte nicht geöffnet werden: fdopen() fehlgeschlagen: %s"
+msgstr "Konfigurationsdatei »%s« konnte nicht geöffnet werden: %s"
 
 #: ../src/pulse/context.c:516
 msgid "No cookie loaded. Attempting to connect without."
@@ -1024,9 +1042,9 @@ msgid "pa_stream_drop() failed: %s\n"
 msgstr "pa_stream_drop() fehlgeschlagen: %s\n"
 
 #: ../src/utils/pacat.c:169
-#, fuzzy, c-format
+#, c-format
 msgid "Stream successfully created.\n"
-msgstr "Cache-Datei wurde erfolgreich erstellt.\n"
+msgstr "Stream wurde erfolgreich erstellt.\n"
 
 #: ../src/utils/pacat.c:172
 #, c-format
@@ -1049,9 +1067,9 @@ msgid "Using sample spec '%s', channel map '%s'.\n"
 msgstr ""
 
 #: ../src/utils/pacat.c:187
-#, fuzzy, c-format
+#, c-format
 msgid "Connected to device %s (%u, %ssuspended).\n"
-msgstr "Zu benutzendes DVD-Device"
+msgstr "Connected to device %s (%u, %ssuspended).\n"
 
 #: ../src/utils/pacat.c:197
 #, c-format
@@ -1059,19 +1077,19 @@ msgid "Stream error: %s\n"
 msgstr "Stream-Fehler: %s\n"
 
 #: ../src/utils/pacat.c:207
-#, fuzzy, c-format
+#, c-format
 msgid "Stream device suspended.%s \n"
-msgstr "ALSA Devicename"
+msgstr "Strom-Gerät eingeschlafen.%s\n"
 
 #: ../src/utils/pacat.c:209
-#, fuzzy, c-format
+#, c-format
 msgid "Stream device resumed.%s \n"
-msgstr "ALSA Devicename"
+msgstr "Stream-Gerät aufgeweckt.%s\n"
 
 #: ../src/utils/pacat.c:217
-#, fuzzy, c-format
+#, c-format
 msgid "Stream underrun.%s \n"
-msgstr "Stream underun.%s \n"
+msgstr "Stream underrun.%s \n"
 
 #: ../src/utils/pacat.c:224
 #, fuzzy, c-format
@@ -1112,36 +1130,31 @@ msgstr "pa_stream_connect_playback() fehlgeschlagen: %s\n"
 msgid "pa_stream_connect_record() failed: %s\n"
 msgstr "pa_stream_connect_record() fehlgeschlagen: %s\n"
 
-#: ../src/utils/pacat.c:307
-#: ../src/utils/pasuspender.c:159
-#: ../src/utils/pactl.c:666
-#: ../src/utils/paplay.c:183
+#: ../src/utils/pacat.c:307 ../src/utils/pasuspender.c:159
+#: ../src/utils/pactl.c:666 ../src/utils/paplay.c:183
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Verbindungsfehler: %s\n"
 
-#: ../src/utils/pacat.c:328
-#: ../src/utils/paplay.c:75
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75
+#, c-format
 msgid "Failed to drain stream: %s\n"
-msgstr "Adresse des Computers, zu dem gestreamt wird."
+msgstr "Entleeren des Streams fehlgeschlagen: %s\n"
 
-#: ../src/utils/pacat.c:333
-#: ../src/utils/paplay.c:80
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80
+#, c-format
 msgid "Playback stream drained.\n"
-msgstr "Bridge-Streamausgabe"
+msgstr "Wiedergabe-Stream entleert.\n"
 
-#: ../src/utils/pacat.c:343
-#: ../src/utils/paplay.c:92
-#, fuzzy, c-format
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
+#, c-format
 msgid "Draining connection to server.\n"
-msgstr "Konnte keine Verbindung zum Server aufbauen"
+msgstr "Draining connection to server.\n"
 
 #: ../src/utils/pacat.c:369
 #, c-format
 msgid "Got EOF.\n"
-msgstr "Erhielt EOF.\n"
+msgstr "EOF empfangen.\n"
 
 #: ../src/utils/pacat.c:375
 #, c-format
@@ -1161,7 +1174,7 @@ msgstr "write() fehlgeschlagen: %s\n"
 #: ../src/utils/pacat.c:438
 #, c-format
 msgid "Got signal, exiting.\n"
-msgstr "Erhielt Signal, verlasse.\n"
+msgstr "Signal empfangen, beende.\n"
 
 #: ../src/utils/pacat.c:452
 #, c-format
@@ -1191,27 +1204,44 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(defaults to s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
 msgstr ""
 
 #: ../src/utils/pacat.c:591
@@ -1278,10 +1308,8 @@ msgstr "dup2(): %s\n"
 msgid "Too many arguments.\n"
 msgstr "Zu viele Argumente.\n"
 
-#: ../src/utils/pacat.c:742
-#: ../src/utils/pasuspender.c:280
-#: ../src/utils/pactl.c:909
-#: ../src/utils/paplay.c:381
+#: ../src/utils/pacat.c:742 ../src/utils/pasuspender.c:280
+#: ../src/utils/pactl.c:909 ../src/utils/paplay.c:381
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
 msgstr "pa_mainloop_new() fehlgeschlagen.\n"
@@ -1291,10 +1319,8 @@ msgstr "pa_mainloop_new() fehlgeschlagen.\n"
 msgid "io_new() failed.\n"
 msgstr "io_new() fehlgeschlagen.\n"
 
-#: ../src/utils/pacat.c:769
-#: ../src/utils/pasuspender.c:293
-#: ../src/utils/pactl.c:923
-#: ../src/utils/paplay.c:396
+#: ../src/utils/pacat.c:769 ../src/utils/pasuspender.c:293
+#: ../src/utils/pactl.c:923 ../src/utils/paplay.c:396
 #, c-format
 msgid "pa_context_new() failed.\n"
 msgstr "pa_context_new() fehlgeschlagen.\n"
@@ -1309,10 +1335,8 @@ msgstr "pa_context_new() fehlgeschlagen: %s"
 msgid "time_new() failed.\n"
 msgstr "time_new() fehlgeschlagen.\n"
 
-#: ../src/utils/pacat.c:795
-#: ../src/utils/pasuspender.c:301
-#: ../src/utils/pactl.c:931
-#: ../src/utils/paplay.c:407
+#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301
+#: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() fehlgeschlagen.\n"
@@ -1342,12 +1366,11 @@ msgstr "Resume fehlgeschlagen: %s\n"
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:176
-#: ../src/utils/pactl.c:672
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
 #: ../src/utils/paplay.c:191
 #, c-format
 msgid "Got SIGINT, exiting.\n"
-msgstr "Erhielt SIGINT, verlasse.\n"
+msgstr "SIGINT empfangen, beende.\n"
 
 #: ../src/utils/pasuspender.c:194
 #, c-format
@@ -1361,14 +1384,16 @@ msgid ""
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 "%s [options] ... \n"
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 
 #: ../src/utils/pasuspender.c:251
@@ -1397,12 +1422,12 @@ msgstr ""
 #: ../src/utils/pactl.c:119
 #, c-format
 msgid "Sample cache size: %s\n"
-msgstr "Sample-Zwischenspeichergrösse: %s\n"
+msgstr "Sample-Pufferspeichergrösse: %s\n"
 
 #: ../src/utils/pactl.c:128
 #, c-format
 msgid "Failed to get server information: %s\n"
-msgstr "Erhalten der Server-Information fehlgeschlagen: %s\n"
+msgstr "Beziehen der Server-Information fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:135
 #, c-format
@@ -1418,7 +1443,7 @@ msgid ""
 msgstr ""
 
 #: ../src/utils/pactl.c:160
-#, fuzzy, c-format
+#, c-format
 msgid "Failed to get sink information: %s\n"
 msgstr "Erhalten der Sink-Information fehlgeschlagen: %s\n"
 
@@ -1439,15 +1464,14 @@ msgid ""
 "%s"
 msgstr ""
 
-#: ../src/utils/pactl.c:193
-#: ../src/utils/pactl.c:371
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
 msgid "muted"
 msgstr "stumm"
 
 #: ../src/utils/pactl.c:212
 #, c-format
 msgid "Failed to get source information: %s\n"
-msgstr "Erhalten der Quellen-Information fehlgeschlagen: %s\n"
+msgstr "Beziehen der Quellen-Information fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:228
 #, c-format
@@ -1466,25 +1490,17 @@ msgid ""
 "%s"
 msgstr ""
 
-#: ../src/utils/pactl.c:246
-#: ../src/utils/pactl.c:289
-#: ../src/utils/pactl.c:322
-#: ../src/utils/pactl.c:366
-#: ../src/utils/pactl.c:367
-#: ../src/utils/pactl.c:374
-#: ../src/utils/pactl.c:418
-#: ../src/utils/pactl.c:419
-#: ../src/utils/pactl.c:425
-#: ../src/utils/pactl.c:468
-#: ../src/utils/pactl.c:469
-#: ../src/utils/pactl.c:473
+#: ../src/utils/pactl.c:246 ../src/utils/pactl.c:289 ../src/utils/pactl.c:322
+#: ../src/utils/pactl.c:366 ../src/utils/pactl.c:367 ../src/utils/pactl.c:374
+#: ../src/utils/pactl.c:418 ../src/utils/pactl.c:419 ../src/utils/pactl.c:425
+#: ../src/utils/pactl.c:468 ../src/utils/pactl.c:469 ../src/utils/pactl.c:473
 msgid "n/a"
 msgstr "k.A."
 
 #: ../src/utils/pactl.c:263
 #, c-format
 msgid "Failed to get module information: %s\n"
-msgstr "Erhalten der Modul-Information fehlgeschlagen: %s\n"
+msgstr "Beziehen der Modul-Information fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:281
 #, c-format
@@ -1499,7 +1515,7 @@ msgstr ""
 #: ../src/utils/pactl.c:298
 #, c-format
 msgid "Failed to get client information: %s\n"
-msgstr "Erhalten der Client-Information fehlgeschlagen: %s\n"
+msgstr "Beziehen der Client-Information fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:316
 #, c-format
@@ -1559,7 +1575,7 @@ msgstr ""
 #: ../src/utils/pactl.c:436
 #, c-format
 msgid "Failed to get sample information: %s\n"
-msgstr "Erhalten der Sample-Information fehlgeschlagen: %s\n"
+msgstr "Beziehen der Sample-Information fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:455
 #, c-format
@@ -1580,7 +1596,7 @@ msgstr ""
 #: ../src/utils/pactl.c:481
 #, c-format
 msgid "Failed to get autoload information: %s\n"
-msgstr "Erhalten der Autoload-Information fehlgeschlagen: %s\n"
+msgstr "Beziehen der Autoload-Information fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:497
 #, c-format
@@ -1600,21 +1616,20 @@ msgstr ""
 msgid "source"
 msgstr "Quelle"
 
-#: ../src/utils/pactl.c:511
-#: ../src/utils/pactl.c:521
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
 #, c-format
 msgid "Failure: %s\n"
-msgstr "Fehlschlag: %s\n"
+msgstr "Fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:545
 #, c-format
 msgid "Failed to upload sample: %s\n"
-msgstr "Hinaufladen des Sample fehlgeschlagen: %s\n"
+msgstr "Hochladen des Sample fehlgeschlagen: %s\n"
 
 #: ../src/utils/pactl.c:562
-#, fuzzy, c-format
+#, c-format
 msgid "Premature end of file\n"
-msgstr "Dateiende ist zu früh aufgetreten"
+msgstr "Dateiende ist zu früh aufgetreten\n"
 
 #: ../src/utils/pactl.c:678
 #, fuzzy, c-format
@@ -1635,8 +1650,10 @@ msgid ""
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 msgstr ""
 "%s [options] stat\n"
 "%s [options] list\n"
@@ -1654,8 +1671,10 @@ msgstr ""
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 
 #: ../src/utils/pactl.c:729
 #, c-format
@@ -1666,7 +1685,7 @@ msgid ""
 msgstr ""
 "pactl %s\n"
 "Kompiliert mit libpulse %s\n"
-"Verknüpft mit libpulse %s\n"
+"Gelinkt mit libpulse %s\n"
 
 #: ../src/utils/pactl.c:768
 #, c-format
@@ -1679,14 +1698,14 @@ msgid "Failed to open sound file.\n"
 msgstr "Öffnen der Audio-Datei fehlgeschlagen.\n"
 
 #: ../src/utils/pactl.c:802
-#, fuzzy, c-format
+#, c-format
 msgid "You have to specify a sample name to play\n"
-msgstr "Es muss ein Repository-Name angegeben werden"
+msgstr "You have to specify a sample name to play\n"
 
 #: ../src/utils/pactl.c:814
-#, fuzzy, c-format
+#, c-format
 msgid "You have to specify a sample name to remove\n"
-msgstr "Es muss ein Paket zum Entfernen angegeben werden"
+msgstr "You have to specify a sample name to remove\n"
 
 #: ../src/utils/pactl.c:822
 #, c-format
@@ -1699,23 +1718,27 @@ msgid "You have to specify a source output index and a source\n"
 msgstr ""
 
 #: ../src/utils/pactl.c:845
-#, fuzzy, c-format
+#, c-format
 msgid "You have to specify a module name and arguments.\n"
-msgstr "Es muss ein Repository-Name/Argument und Wert angegeben werden"
+msgstr "You have to specify a module name and arguments.\n"
 
 #: ../src/utils/pactl.c:865
-#, fuzzy, c-format
+#, c-format
 msgid "You have to specify a module index\n"
-msgstr "Geben Sie das zu benutzende Deinterlace-Modul an."
+msgstr "You have to specify a module index\n"
 
 #: ../src/utils/pactl.c:875
 #, c-format
-msgid "You may not specify more than one sink. You have to specify at least one boolean value.\n"
+msgid ""
+"You may not specify more than one sink. You have to specify at least one "
+"boolean value.\n"
 msgstr ""
 
 #: ../src/utils/pactl.c:888
 #, c-format
-msgid "You may not specify more than one source. You have to specify at least one boolean value.\n"
+msgid ""
+"You may not specify more than one source. You have to specify at least one "
+"boolean value.\n"
 msgstr ""
 
 #: ../src/utils/pactl.c:904
@@ -1730,20 +1753,22 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 "%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 
 #: ../src/utils/pax11publish.c:94
-#, fuzzy, c-format
+#, c-format
 msgid "Failed to parse command line.\n"
-msgstr "Parsen der Port-Nummer fehlgeschlagen: %s\n"
+msgstr "Parsen der Kommandozeile fehlgeschlagen.\n"
 
 #: ../src/utils/pax11publish.c:108
 #, c-format
@@ -1766,9 +1791,9 @@ msgid "Cookie: %s\n"
 msgstr "Cookie: %s\n"
 
 #: ../src/utils/pax11publish.c:132
-#, fuzzy, c-format
+#, c-format
 msgid "Failed to parse cookie data\n"
-msgstr "TIFF-Daten konnten nicht gespeichert werden"
+msgstr "Paresen der Cookie-Daten fehlgeschlagen.\n"
 
 #: ../src/utils/pax11publish.c:137
 #, c-format
@@ -1778,12 +1803,12 @@ msgstr "Speichern der Cookie-Daten fehlgeschlagen\n"
 #: ../src/utils/pax11publish.c:152
 #, c-format
 msgid "Failed to load client configuration file.\n"
-msgstr "Laden der Client-Konfigurationsdatei fehlgeschlagen\n"
+msgstr "Laden der Client-Konfigurationsdatei fehlgeschlagen.\n"
 
 #: ../src/utils/pax11publish.c:157
-#, fuzzy, c-format
+#, c-format
 msgid "Failed to read environment configuration data.\n"
-msgstr "Daten konnten nicht vom Kindprozess gelesen werden"
+msgstr "Lesen the Umgebungsdaten fehlgeschlagen.\n"
 
 #: ../src/utils/pax11publish.c:174
 #, c-format
@@ -1798,7 +1823,7 @@ msgstr "Laden der Cookie-Daten fehlgeschlagen\n"
 #: ../src/utils/pax11publish.c:211
 #, c-format
 msgid "Not yet implemented.\n"
-msgstr "Momentan nicht implementiert.\n"
+msgstr "Noch nicht implementiert.\n"
 
 #: ../src/utils/pacmd.c:64
 #, c-format
@@ -1812,7 +1837,7 @@ msgstr "connect(): %s"
 
 #: ../src/utils/pacmd.c:89
 msgid "Failed to kill PulseAudio daemon."
-msgstr "Abwürgen des PulseAudio-Daemon fehlgeschlagen."
+msgstr "Terminieren des PulseAudio-Daemon fehlgeschlagen."
 
 #: ../src/utils/pacmd.c:97
 msgid "Daemon not responding."
@@ -1823,14 +1848,12 @@ msgstr "Daemon antwortet nicht."
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124
-#: ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153
-#: ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
@@ -1860,11 +1883,15 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operation\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "  -d, --device=DEVICE                   The name of the sink to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
 "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 msgstr ""
 "%s [options] [FILE]\n"
@@ -1874,11 +1901,15 @@ msgstr ""
 "\n"
 "  -v, --verbose                         Enable verbose operation\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "  -d, --device=DEVICE                   The name of the sink to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
 "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 
 #: ../src/utils/paplay.c:255
@@ -1890,7 +1921,7 @@ msgid ""
 msgstr ""
 "paplay %s\n"
 "Kompliert mit libpulse %s\n"
-"Verknüpft mit libpulse %s\n"
+"Gelinkt mit libpulse %s\n"
 
 #: ../src/utils/paplay.c:292
 #, c-format
@@ -1905,19 +1936,16 @@ msgstr "Öffnen der Datei '%s' fehlgeschlagen\n"
 #: ../src/utils/paplay.c:350
 #, c-format
 msgid "Channel map doesn't match file.\n"
-msgstr "KAnal-Auflistung stimmt mit DAtei nicht überein.\n"
+msgstr "Kanal-Zuweisung stimmt mit Datei nicht überein.\n"
 
 #: ../src/utils/paplay.c:376
 #, c-format
 msgid "Using sample spec '%s'\n"
-msgstr "Beispiel-Spec '%s' wird benutzt\n"
+msgstr "Sampling-Spezifikation '%s' wird benutzt\n"
 
-#: ../src/pulsecore/lock-autospawn.c:126
-#: ../src/pulsecore/lock-autospawn.c:207
-#, fuzzy
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
 msgid "Cannot access autospawn lock."
-msgstr "Fehler beim Zugriff auf automatische Sperre."
+msgstr "Fehler beim Zugriff auf Autostart -Sperre."
 
 #~ msgid "socketpair(): %s"
 #~ msgstr "socketpair(): %s"
-
index b664491b79513f6c673417155738e3633fec03c9..79ccda739255113f4512a28c21b775991e7db48c 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: el\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-08-22 19:36+0300\n"
+"POT-Creation-Date: 2008-10-07 21:03+0200\n"
 "PO-Revision-Date: 2008-08-22 19:40+0300\n"
 "Last-Translator: Dimitris Glezos <dimitris@glezos.com>\n"
 "Language-Team: Greek <fedora-trans-el@redhat.com>\n"
@@ -283,42 +283,78 @@ msgstr "Αυτό είναι το PulseAudio %s"
 
 #: ../src/daemon/main.c:781
 #, c-format
+msgid "Compilation host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:782
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:785
+#, c-format
+msgid "Running on host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:788
+#, c-format
 msgid "Page size is %lu bytes"
 msgstr ""
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:791
+msgid "Compiled with Valgrind support: yes"
+msgstr ""
+
+#: ../src/daemon/main.c:793
+msgid "Compiled with Valgrind support: no"
+msgstr ""
+
+#: ../src/daemon/main.c:796
+#, c-format
+msgid "Running in valgrind mode: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:799
+msgid "Optimized build: yes"
+msgstr ""
+
+#: ../src/daemon/main.c:801
+msgid "Optimized build: no"
+msgstr ""
+
+#: ../src/daemon/main.c:805
 msgid "Failed to get machine ID"
 msgstr ""
 
-#: ../src/daemon/main.c:787
+#: ../src/daemon/main.c:808
 #, c-format
 msgid "Machine ID is %s."
 msgstr ""
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:813
 #, c-format
 msgid "Using runtime directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:797
+#: ../src/daemon/main.c:818
 #, c-format
 msgid "Using state directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:800
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Running in system mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:815
+#: ../src/daemon/main.c:836
 msgid "pa_pid_file_create() failed."
 msgstr ""
 
-#: ../src/daemon/main.c:827
+#: ../src/daemon/main.c:848
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:850
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -326,32 +362,32 @@ msgstr ""
 "Δικέ μου, ο πυρήνας σου είναι για τα μπάζα! Η πρόταση του σεφ σήμερα είναι "
 "Linux με ενεργοποιημένα τα high-resolution timers!"
 
-#: ../src/daemon/main.c:839
+#: ../src/daemon/main.c:860
 msgid "pa_core_new() failed."
 msgstr ""
 
-#: ../src/daemon/main.c:899
+#: ../src/daemon/main.c:921
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:904
+#: ../src/daemon/main.c:926
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:909
+#: ../src/daemon/main.c:931
 #, c-format
 msgid "Default sink name (%s) does not exist in name register."
 msgstr ""
 
-#: ../src/daemon/main.c:922
+#: ../src/daemon/main.c:944
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:928
+#: ../src/daemon/main.c:950
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:949
+#: ../src/daemon/main.c:971
 msgid "Daemon terminated."
 msgstr ""
 
@@ -519,76 +555,76 @@ msgstr ""
 msgid "Path: %s\n"
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:203
+#: ../src/daemon/daemon-conf.c:205
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:219
+#: ../src/daemon/daemon-conf.c:221
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:235
+#: ../src/daemon/daemon-conf.c:237
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:258
+#: ../src/daemon/daemon-conf.c:260
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:265
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:281
+#: ../src/daemon/daemon-conf.c:283
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:299
+#: ../src/daemon/daemon-conf.c:301
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:317
+#: ../src/daemon/daemon-conf.c:319
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:335
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:353
+#: ../src/daemon/daemon-conf.c:355
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:371
+#: ../src/daemon/daemon-conf.c:373
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:564
+#: ../src/daemon/daemon-conf.c:570
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:644
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr ""
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
 msgid "Dropping root priviliges."
 msgstr ""
 
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
@@ -796,6 +832,11 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
+#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
+#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+msgid "(invalid)"
+msgstr ""
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr ""
@@ -884,10 +925,6 @@ msgstr ""
 msgid "No such extension"
 msgstr ""
 
-#: ../src/pulse/sample.c:134
-msgid "Invalid"
-msgstr ""
-
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr ""
@@ -896,31 +933,26 @@ msgstr ""
 msgid "Failed to parse cookie data"
 msgstr ""
 
-#: ../src/pulse/client-conf.c:117
+#: ../src/pulse/client-conf.c:120
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr ""
 
-#: ../src/pulse/context.c:542
+#: ../src/pulse/context.c:516
 msgid "No cookie loaded. Attempting to connect without."
 msgstr ""
 
-#: ../src/pulse/context.c:596
-#, c-format
-msgid "socketpair(): %s"
-msgstr ""
-
-#: ../src/pulse/context.c:610
+#: ../src/pulse/context.c:642
 #, c-format
 msgid "fork(): %s"
 msgstr ""
 
-#: ../src/pulse/context.c:673
+#: ../src/pulse/context.c:695
 #, c-format
 msgid "waitpid(): %s"
 msgstr ""
 
-#: ../src/pulse/context.c:1354
+#: ../src/pulse/context.c:1256
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr ""
@@ -1122,8 +1154,8 @@ msgid ""
 "44100)\n"
 "      --format=SAMPLEFORMAT             The sample type, one of s16le, "
 "s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw (defaults to "
-"s16ne)\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(defaults to s16ne)\n"
 "      --channels=CHANNELS               The number of channels, 1 for mono, "
 "2 for stereo\n"
 "                                        (defaults to 2)\n"
@@ -1226,12 +1258,17 @@ msgstr ""
 msgid "pa_context_new() failed.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:785
+#: ../src/utils/pacat.c:777
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr ""
+
+#: ../src/utils/pacat.c:788
 #, c-format
 msgid "time_new() failed.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:792 ../src/utils/pasuspender.c:301
+#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301
 #: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
@@ -1782,3 +1819,6 @@ msgstr ""
 msgid "Using sample spec '%s'\n"
 msgstr ""
 
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
+msgid "Cannot access autospawn lock."
+msgstr ""
index 9cd91bf393b2892ba42855e8b36fe7b27c146e85..6d35390a7bddbe2b8884884ebb84b86224f0a27c 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio trunk\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-06 06:06+0000\n"
+"POT-Creation-Date: 2008-10-07 21:03+0200\n"
 "PO-Revision-Date: 2008-09-06 10:49+0200\n"
 "Last-Translator: Robert-André Mauchin <zebob.m@pengzone.org>\n"
 "Language-Team: Fedora French <fedora-trans-fr@redhat.com>\n"
@@ -192,22 +192,6 @@ msgstr ""
 "nécessaires :\n"
 "nous ne somme pas dans le groupe "
 
-#: ../src/daemon/main.c:480
-msgid ""
-"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
-"For enabling real-time scheduling please acquire the appropriate PolicyKit "
-"priviliges, or become a member of '"
-msgstr ""
-" et PolicyKit refuse de nous accorder les permissions. Abandon du SUID à nouveau.\n"
-"Pour activer la planification en temps réel, veuillez aquérir les permissions "
-"PolicyKit appropriées, ou devenez membre de "
-
-#: ../src/daemon/main.c:481
-msgid ""
-"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
-msgstr ""
-", ou augmentez les limites de ressource RLIMIT_NICE/RLIMIT_RTPRIO pour cet utilisateur."
-
 #: ../src/daemon/main.c:497
 msgid ""
 "High-priority scheduling enabled in configuration but not allowed by policy."
@@ -319,65 +303,80 @@ msgid "This is PulseAudio %s"
 msgstr "Pulseaudio %s"
 
 #: ../src/daemon/main.c:781
+#, fuzzy, c-format
+msgid "Compilation host: %s"
+msgstr "CFLAGS de compilation : %s"
+
+#: ../src/daemon/main.c:782
 #, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr "CFLAGS de compilation : %s"
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:785
+#, fuzzy, c-format
+msgid "Running on host: %s"
+msgstr "Exécution en mode système : %s"
+
+#: ../src/daemon/main.c:788
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr "La taille de la page est de %lu octets"
+
+#: ../src/daemon/main.c:791
 msgid "Compiled with Valgrind support: yes"
 msgstr "Compilé avec la prise en charge Valgrind : oui"
 
-#: ../src/daemon/main.c:786
+#: ../src/daemon/main.c:793
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilé avec la prise en charge Valgrind : non"
 
-#: ../src/daemon/main.c:790
+#: ../src/daemon/main.c:796
+#, fuzzy, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "Exécution en mode système : %s"
+
+#: ../src/daemon/main.c:799
 msgid "Optimized build: yes"
 msgstr "Construction optimisée : oui"
 
-#: ../src/daemon/main.c:792
+#: ../src/daemon/main.c:801
 msgid "Optimized build: no"
 msgstr "Construction optimisée : non"
 
-#: ../src/daemon/main.c:795
-#, c-format
-msgid "Page size is %lu bytes"
-msgstr "La taille de la page est de %lu octets"
-
-#: ../src/daemon/main.c:798
+#: ../src/daemon/main.c:805
 msgid "Failed to get machine ID"
 msgstr "Échec lors de l'obtention de l'ID de la machine"
 
-#: ../src/daemon/main.c:801
+#: ../src/daemon/main.c:808
 #, c-format
 msgid "Machine ID is %s."
 msgstr "L'ID de la machine est %s."
 
-#: ../src/daemon/main.c:806
+#: ../src/daemon/main.c:813
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Utilisation du répertoire d'exécution %s."
 
-#: ../src/daemon/main.c:811
+#: ../src/daemon/main.c:818
 #, c-format
 msgid "Using state directory %s."
 msgstr "Utilisation du répertoire d'état %s."
 
-#: ../src/daemon/main.c:814
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Exécution en mode système : %s"
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:836
 msgid "pa_pid_file_create() failed."
 msgstr "Échec de pa_pid_file_create()."
 
-#: ../src/daemon/main.c:841
+#: ../src/daemon/main.c:848
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 "De nouvelles horloges à haute résolution sont disponibles ! Bon appétit !"
 
-#: ../src/daemon/main.c:843
+#: ../src/daemon/main.c:850
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -385,34 +384,34 @@ msgstr ""
 "Eh mec, ton noyau il pue ! La recommandation d'aujourd'hui du patron est "
 "d'activer les horloges à haute résolution sur ton Linux."
 
-#: ../src/daemon/main.c:853
+#: ../src/daemon/main.c:860
 msgid "pa_core_new() failed."
 msgstr "Échec de pa_core_new()."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:921
 msgid "Failed to initialize daemon."
 msgstr "Échec lors de l'initialisation du démon"
 
-#: ../src/daemon/main.c:918
+#: ../src/daemon/main.c:926
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Démarrage du démon sans aucun module chargé : refus de fonctionner."
 
-#: ../src/daemon/main.c:923
+#: ../src/daemon/main.c:931
 #, c-format
 msgid "Default sink name (%s) does not exist in name register."
 msgstr ""
 "Le nom de la destination par défaut (%s) n'existe pas dans le registre des "
 "noms."
 
-#: ../src/daemon/main.c:936
+#: ../src/daemon/main.c:944
 msgid "Daemon startup complete."
 msgstr "Démarrage du démon effectué."
 
-#: ../src/daemon/main.c:942
+#: ../src/daemon/main.c:950
 msgid "Daemon shutdown initiated."
 msgstr "Fermeture du démon initiée."
 
-#: ../src/daemon/main.c:963
+#: ../src/daemon/main.c:971
 msgid "Daemon terminated."
 msgstr "Démon terminé."
 
@@ -664,76 +663,76 @@ msgid "Path: %s\n"
 msgstr "Chemin : %s\n"
 
 # dans les lignes suivantes [%s = nom de fichier: %u = ligne dans celui-ci]
-#: ../src/daemon/daemon-conf.c:203
+#: ../src/daemon/daemon-conf.c:205
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Cible du journal « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:219
+#: ../src/daemon/daemon-conf.c:221
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Niveau du journal « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:235
+#: ../src/daemon/daemon-conf.c:237
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Méthode de rééchantillonnage « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:258
+#: ../src/daemon/daemon-conf.c:260
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:265
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr "[%s:%u] rlimit n'est pas pris en charge sur cette plateforme."
 
-#: ../src/daemon/daemon-conf.c:281
+#: ../src/daemon/daemon-conf.c:283
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Format d'échantillon « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:299
+#: ../src/daemon/daemon-conf.c:301
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Taux d'échantillonnage « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:317
+#: ../src/daemon/daemon-conf.c:319
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canaux d'échantillonnage « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:335
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Nombre de fragments « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:353
+#: ../src/daemon/daemon-conf.c:355
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Taille du fragment « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:371
+#: ../src/daemon/daemon-conf.c:373
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Niveau de priorité (nice) « %s » invalide."
 
-#: ../src/daemon/daemon-conf.c:564
+#: ../src/daemon/daemon-conf.c:570
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Échec lors de l'ouverture du fichier de configuration : %s"
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:644
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lecture à partir du fichier de configuration : %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
 msgid "Dropping root priviliges."
 msgstr "Abandon des permissions root."
 
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Limitation des capacités à CAP_SYS_NICE réussie."
 
@@ -941,6 +940,12 @@ msgstr "Arrière gauche haut"
 msgid "Top Rear Right"
 msgstr "Arrière droit haut"
 
+#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
+#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+#, fuzzy
+msgid "(invalid)"
+msgstr "Invalide"
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr "OK"
@@ -1029,10 +1034,6 @@ msgstr "Code d'erreur inconnu"
 msgid "No such extension"
 msgstr "Aucune extension de ce type"
 
-#: ../src/pulse/sample.c:134
-msgid "Invalid"
-msgstr "Invalide"
-
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "Échec de XOpenDisplay()"
@@ -1041,31 +1042,26 @@ msgstr "Échec de XOpenDisplay()"
 msgid "Failed to parse cookie data"
 msgstr "Échec lors de l'analyse des données du cookie"
 
-#: ../src/pulse/client-conf.c:117
+#: ../src/pulse/client-conf.c:120
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Échec lors de l'ouverture du fichier de configuration « %s » :%s"
 
-#: ../src/pulse/context.c:542
+#: ../src/pulse/context.c:516
 msgid "No cookie loaded. Attempting to connect without."
 msgstr "Aucun cookie chargé. Tentative de connexion sans celui-ci."
 
-#: ../src/pulse/context.c:596
-#, c-format
-msgid "socketpair(): %s"
-msgstr "socketpair() : %s"
-
-#: ../src/pulse/context.c:610
+#: ../src/pulse/context.c:642
 #, c-format
 msgid "fork(): %s"
 msgstr "fork() : %s"
 
-#: ../src/pulse/context.c:673
+#: ../src/pulse/context.c:695
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid() : %s"
 
-#: ../src/pulse/context.c:1354
+#: ../src/pulse/context.c:1256
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr "Message reçu pour une extension inconnue « %s »"
@@ -1247,7 +1243,7 @@ msgstr "Échec de pa_stream_update_timing_info() : %s\n"
 # upmixer = par ex. convertir 2 canaux en 5 canaux
 # https://bugzilla.redhat.com/show_bug.cgi?id=460798
 #: ../src/utils/pacat.c:490
-#, c-format
+#, fuzzy, c-format
 msgid ""
 "%s [options]\n"
 "\n"
@@ -1273,8 +1269,8 @@ msgid ""
 "44100)\n"
 "      --format=SAMPLEFORMAT             The sample type, one of s16le, "
 "s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw (defaults to "
-"s16ne)\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(defaults to s16ne)\n"
 "      --channels=CHANNELS               The number of channels, 1 for mono, "
 "2 for stereo\n"
 "                                        (defaults to 2)\n"
@@ -1431,12 +1427,17 @@ msgstr "Échec de io_new().\n"
 msgid "pa_context_new() failed.\n"
 msgstr "Échec de pa_context_new().\n"
 
-#: ../src/utils/pacat.c:785
+#: ../src/utils/pacat.c:777
+#, fuzzy, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "Échec de pa_context_new().\n"
+
+#: ../src/utils/pacat.c:788
 #, c-format
 msgid "time_new() failed.\n"
 msgstr "Échec de time_new().\n"
 
-#: ../src/utils/pacat.c:792 ../src/utils/pasuspender.c:301
+#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301
 #: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
@@ -2151,3 +2152,27 @@ msgstr "Le plan des canaux ne correspond pas au fichier.\n"
 #, c-format
 msgid "Using sample spec '%s'\n"
 msgstr "Utilisation de la spécification de l'échantillon « %s »\n"
+
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
+msgid "Cannot access autospawn lock."
+msgstr ""
+
+#~ msgid ""
+#~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
+#~ "For enabling real-time scheduling please acquire the appropriate "
+#~ "PolicyKit priviliges, or become a member of '"
+#~ msgstr ""
+#~ " et PolicyKit refuse de nous accorder les permissions. Abandon du SUID à "
+#~ "nouveau.\n"
+#~ "Pour activer la planification en temps réel, veuillez aquérir les "
+#~ "permissions PolicyKit appropriées, ou devenez membre de "
+
+#~ msgid ""
+#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
+#~ "user."
+#~ msgstr ""
+#~ ", ou augmentez les limites de ressource RLIMIT_NICE/RLIMIT_RTPRIO pour "
+#~ "cet utilisateur."
+
+#~ msgid "socketpair(): %s"
+#~ msgstr "socketpair() : %s"
index 4be8e060b98700852c86a59561d14664fcf71bc3..5c5b3b4f14b910f01436864df4943ffb3c2b44b9 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pl\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-09 21:39+0200\n"
+"POT-Creation-Date: 2008-10-07 21:03+0200\n"
 "PO-Revision-Date: 2008-09-10 22:41+0200\n"
 "Last-Translator: Piotr Drąg <piotrdrag@gmail.com>\n"
 "Language-Team: Polish <pl@li.org>\n"
@@ -324,47 +324,52 @@ msgstr "Skompilowano z obsługą Valgrind: tak"
 msgid "Compiled with Valgrind support: no"
 msgstr "Skompilowano z obsługą Valgrind: nie"
 
-#: ../src/daemon/main.c:797
+#: ../src/daemon/main.c:796
+#, fuzzy, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "Uruchamianie w trybie systemowym: %s"
+
+#: ../src/daemon/main.c:799
 msgid "Optimized build: yes"
 msgstr "Budowanie optymalizowane: tak"
 
-#: ../src/daemon/main.c:799
+#: ../src/daemon/main.c:801
 msgid "Optimized build: no"
 msgstr "Budowanie optymalizowane: nie"
 
-#: ../src/daemon/main.c:803
+#: ../src/daemon/main.c:805
 msgid "Failed to get machine ID"
 msgstr "Uzyskanie identyfikatora komputera nie powiodło się"
 
-#: ../src/daemon/main.c:806
+#: ../src/daemon/main.c:808
 #, c-format
 msgid "Machine ID is %s."
 msgstr "Identyfikator komputera to %s."
 
-#: ../src/daemon/main.c:811
+#: ../src/daemon/main.c:813
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Używanie folderu wykonywania %s."
 
-#: ../src/daemon/main.c:816
+#: ../src/daemon/main.c:818
 #, c-format
 msgid "Using state directory %s."
 msgstr "Używanie folderu stanu %s."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Uruchamianie w trybie systemowym: %s"
 
-#: ../src/daemon/main.c:834
+#: ../src/daemon/main.c:836
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() nie powiodło się."
 
-#: ../src/daemon/main.c:846
+#: ../src/daemon/main.c:848
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Świeże zegary o wysokiej rozdzielczości! Smacznego!"
 
-#: ../src/daemon/main.c:848
+#: ../src/daemon/main.c:850
 msgid ""
 "Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
 "resolution timers enabled!"
@@ -372,32 +377,32 @@ msgstr ""
 "Koleś, twoje jądro śmierdzi! Szef kuchni poleca dzisiaj Linuksa w włączonymi "
 "zegarami o wysokiej rozdzielczości!"
 
-#: ../src/daemon/main.c:858
+#: ../src/daemon/main.c:860
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() nie powiodło się."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:921
 msgid "Failed to initialize daemon."
 msgstr "Zainicjowanie demona nie powiodło się."
 
-#: ../src/daemon/main.c:924
+#: ../src/daemon/main.c:926
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr "Uruchamianie demona bez żadnych wczytanych modułów, odmawianie pracy."
 
-#: ../src/daemon/main.c:929
+#: ../src/daemon/main.c:931
 #, c-format
 msgid "Default sink name (%s) does not exist in name register."
 msgstr "Domyślna nazwa odpływu (%s) nie istnieje w rejestrze nazw."
 
-#: ../src/daemon/main.c:942
+#: ../src/daemon/main.c:944
 msgid "Daemon startup complete."
 msgstr "Zakończono uruchamianie demona."
 
-#: ../src/daemon/main.c:948
+#: ../src/daemon/main.c:950
 msgid "Daemon shutdown initiated."
 msgstr "Zainicjowano wyłączenie demona."
 
-#: ../src/daemon/main.c:969
+#: ../src/daemon/main.c:971
 msgid "Daemon terminated."
 msgstr "Demon został zniszczony."
 
@@ -501,8 +506,8 @@ msgstr ""
 "                                        z podniesionym RLIMIT_RTPRIO)\n"
 "      --disallow-module-loading[=ZMIENNALOGICZNA] Nie zezwala użytkownikowi "
 "modułu na\n"
-"                                        żądanie wczytania/usunięcia modułu po "
-"uruchomieniu\n"
+"                                        żądanie wczytania/usunięcia modułu "
+"po uruchomieniu\n"
 "      --disallow-exit[=ZMIENNALOGICZNA] Nie zezwala użytkownikowi na żądanie "
 "wyłączenia\n"
 "      --exit-idle-time=SEKUNDY          Niszczy demona, kiedy jest zajęty i "
@@ -642,76 +647,76 @@ msgstr "Wczytanie jednorazowe: %s\n"
 msgid "Path: %s\n"
 msgstr "Ścieżka: %s\n"
 
-#: ../src/daemon/daemon-conf.c:204
+#: ../src/daemon/daemon-conf.c:205
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Nieprawidłowy dziennik docelowy \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:220
+#: ../src/daemon/daemon-conf.c:221
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nieprawidłowy poziom dziennika \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:236
+#: ../src/daemon/daemon-conf.c:237
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Nieprawidłowa metoda resamplingu \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:259
+#: ../src/daemon/daemon-conf.c:260
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] Nieprawidłowy rlimit \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:266
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr "[%s:%u] rlimit nie jest obsługiwany na tej platformie."
 
-#: ../src/daemon/daemon-conf.c:282
+#: ../src/daemon/daemon-conf.c:283
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Nieprawidłowy format próbki \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:300
+#: ../src/daemon/daemon-conf.c:301
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Nieprawidłowa częstotliwość próbki \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:318
+#: ../src/daemon/daemon-conf.c:319
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Nieprawidłowe kanały próbki \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:336
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Nieprawidłowa liczba fragmentów \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:354
+#: ../src/daemon/daemon-conf.c:355
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Nieprawidłowy rozmiar fragmentu \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:372
+#: ../src/daemon/daemon-conf.c:373
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Nieprawidłowy poziom nice \"%s\"."
 
-#: ../src/daemon/daemon-conf.c:567
+#: ../src/daemon/daemon-conf.c:570
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Otwarcie pliku konfiguracji nie powiodło się: %s"
 
-#: ../src/daemon/daemon-conf.c:641
+#: ../src/daemon/daemon-conf.c:644
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Odczytano z pliku konfiguracji: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
 msgid "Dropping root priviliges."
 msgstr "Porzucanie uprawnień roota."
 
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "Pomyślnie ograniczono możliwości do CAP_SYS_NICE."
 
@@ -919,6 +924,12 @@ msgstr "Górny tylny lewy"
 msgid "Top Rear Right"
 msgstr "Górny tylny prawy"
 
+#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
+#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+#, fuzzy
+msgid "(invalid)"
+msgstr "Nieprawidłowe"
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr "OK"
@@ -1007,10 +1018,6 @@ msgstr "Nieznany kod błędu"
 msgid "No such extension"
 msgstr "Nie ma takiego rozszerzenia"
 
-#: ../src/pulse/sample.c:134
-msgid "Invalid"
-msgstr "Nieprawidłowe"
-
 #: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() nie powiodło się"
@@ -1019,7 +1026,7 @@ msgstr "XOpenDisplay() nie powiodło się"
 msgid "Failed to parse cookie data"
 msgstr "Analiza danych ciasteczka nie powiodło się"
 
-#: ../src/pulse/client-conf.c:117
+#: ../src/pulse/client-conf.c:120
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Otwarcie pliku konfiguracji \"%s\" nie powiodło się: %s"
@@ -1748,7 +1755,8 @@ msgstr ""
 #: ../src/utils/pactl.c:481
 #, c-format
 msgid "Failed to get autoload information: %s\n"
-msgstr "Uzyskanie informacji o automatycznym wczytywaniu nie powiodło się: %s\n"
+msgstr ""
+"Uzyskanie informacji o automatycznym wczytywaniu nie powiodło się: %s\n"
 
 #: ../src/utils/pactl.c:497
 #, c-format
index 8bf905b05418a58709ff01113e4f0d721c45a395..94494f7f2fd07dbcb8894e3471453ac5bf67aab2 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-09 03:32+0000\n"
+"POT-Creation-Date: 2008-10-07 21:03+0200\n"
 "PO-Revision-Date: 2008-09-21 17:05-0300\n"
 "Last-Translator: Herli Menezes <herlimenezes@gmail.com>\n"
 "Language-Team: Brazilian-Portuguese <fedora-trans-pt_br@redhat.com>\n"
@@ -18,8 +18,7 @@ msgstr ""
 "X-Poedit-Language: Brazilian Portuguese\n"
 "X-Poedit-Country: Brazil\n"
 
-#: ../src/daemon/ltdl-bind-now.c:177
-#: ../src/daemon/ltdl-bind-now.c:197
+#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
 msgid "Failed to add bind-now-loader."
 msgstr "Falha em adicionar o bind-now-loader."
 
@@ -115,8 +114,7 @@ msgstr "O GID do usuário'%s' e do grupo '%s' não combinam."
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "O diretório Home do usuário '%s' não é '%s', ignorando."
 
-#: ../src/daemon/main.c:201
-#: ../src/daemon/main.c:206
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Falha em criar '%s': %s"
@@ -181,27 +179,21 @@ msgstr "O PolicyKit recusa a aquisição de privilégios de tempo real."
 
 #: ../src/daemon/main.c:479
 msgid ""
-"Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
+"Called SUID root and real-time/high-priority scheduling was requested in the "
+"configuration. However, we lack the necessary priviliges:\n"
 "We are not in group '"
 msgstr ""
-"A chamada de SUID root e tempo real/alta prioridade no escalonamento foi requisitada pela configuração. Todavia, falta-nos os privilégios necessários:\n"
+"A chamada de SUID root e tempo real/alta prioridade no escalonamento foi "
+"requisitada pela configuração. Todavia, falta-nos os privilégios "
+"necessários:\n"
 "Não estamos no grupo'"
 
-#: ../src/daemon/main.c:480
+#: ../src/daemon/main.c:497
 msgid ""
-"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
-"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"
+"High-priority scheduling enabled in configuration but not allowed by policy."
 msgstr ""
-"' e o PolicyKit recusa-nos a garantia de privilégios. Retirando o SUID outra vez.\n"
-" Para habilitar o escalonamento em tempo real, por favo, adquira os privilégios adequados pelo PolicyKit, ou torne-se membro do'"
-
-#: ../src/daemon/main.c:481
-msgid "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
-msgstr "', ou eleve o RLIMIT_NICE/RLIMIT_RTPRIO dos limites do recurso para este usuário."
-
-#: ../src/daemon/main.c:497
-msgid "High-priority scheduling enabled in configuration but not allowed by policy."
-msgstr "O escalonamento de alta prioridade foi habilitado para esta configuração, mas não é permitida pela política."
+"O escalonamento de alta prioridade foi habilitado para esta configuração, "
+"mas não é permitida pela política."
 
 #: ../src/daemon/main.c:522
 msgid "Successfully increased RLIMIT_RTPRIO"
@@ -217,8 +209,11 @@ msgid "Giving up CAP_NICE"
 msgstr "Abandonando CAP_NICE"
 
 #: ../src/daemon/main.c:539
-msgid "Real-time scheduling enabled in configuration but not allowed by policy."
-msgstr "O escalonamento de tempo real foi habilitado pela configuração, mas não é permitido pela política."
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+"O escalonamento de tempo real foi habilitado pela configuração, mas não é "
+"permitido pela política."
 
 #: ../src/daemon/main.c:597
 msgid "Daemon not running"
@@ -235,8 +230,12 @@ msgid "Failed to kill daemon: %s"
 msgstr "Falha em encerrar o daemon: %s"
 
 #: ../src/daemon/main.c:627
-msgid "This program is not intended to be run as root (unless --system is specified)."
-msgstr "Este programa não é para ser executado como root (a não ser que --system seja especificado)."
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Este programa não é para ser executado como root (a não ser que --system "
+"seja especificado)."
 
 #: ../src/daemon/main.c:629
 msgid "Root priviliges required."
@@ -252,7 +251,8 @@ msgstr "Executando em no modo system, mas --disallow-exit não foi configurado!"
 
 #: ../src/daemon/main.c:642
 msgid "Running in system mode, but --disallow-module-loading not set!"
-msgstr "Executando no modo system, mas --disallow-module-loading não foi configurado!"
+msgstr ""
+"Executando no modo system, mas --disallow-module-loading não foi configurado!"
 
 #: ../src/daemon/main.c:645
 msgid "Running in system mode, forcibly disabling SHM mode!"
@@ -260,7 +260,8 @@ msgstr "Executando no modo system, desabilitando forçadamente o modo SHM!"
 
 #: ../src/daemon/main.c:650
 msgid "Running in system mode, forcibly disabling exit idle time!"
-msgstr "Executando no modo system, desabilitando forçadamente o exit idle time!"
+msgstr ""
+"Executando no modo system, desabilitando forçadamente o exit idle time!"
 
 #: ../src/daemon/main.c:677
 msgid "Failed to acquire stdio."
@@ -322,76 +323,86 @@ msgstr "Compilado com suporte do Valgrind: sim"
 msgid "Compiled with Valgrind support: no"
 msgstr "Compilado com suporte do Valgrind: não"
 
-#: ../src/daemon/main.c:797
+#: ../src/daemon/main.c:796
+#, fuzzy, c-format
+msgid "Running in valgrind mode: %s"
+msgstr "Executando em modo do sistema: %s"
+
+#: ../src/daemon/main.c:799
 msgid "Optimized build: yes"
 msgstr "Build otimizado: sim"
 
-#: ../src/daemon/main.c:799
+#: ../src/daemon/main.c:801
 msgid "Optimized build: no"
 msgstr "Build otimizado: não"
 
-#: ../src/daemon/main.c:803
+#: ../src/daemon/main.c:805
 msgid "Failed to get machine ID"
 msgstr "Falha em obter o ID da máquina"
 
-#: ../src/daemon/main.c:806
+#: ../src/daemon/main.c:808
 #, c-format
 msgid "Machine ID is %s."
 msgstr "A ID da máquina é %s."
 
-#: ../src/daemon/main.c:811
+#: ../src/daemon/main.c:813
 #, c-format
 msgid "Using runtime directory %s."
 msgstr "Usando o diretório de runtime %s."
 
-#: ../src/daemon/main.c:816
+#: ../src/daemon/main.c:818
 #, c-format
 msgid "Using state directory %s."
 msgstr "Usando o diretório de estado %s."
 
-#: ../src/daemon/main.c:819
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Running in system mode: %s"
 msgstr "Executando em modo do sistema: %s"
 
-#: ../src/daemon/main.c:834
+#: ../src/daemon/main.c:836
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() falhou."
 
-#: ../src/daemon/main.c:846
+#: ../src/daemon/main.c:848
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr "Timers de alta resolução frequinhos disponíveis! Bon appetit!"
 
-#: ../src/daemon/main.c:848
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
-msgstr "Cara, teu kernel fede! A recomendação do chef hoje é Linux com timers de alta resolução habilitados!"
+#: ../src/daemon/main.c:850
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Cara, teu kernel fede! A recomendação do chef hoje é Linux com timers de "
+"alta resolução habilitados!"
 
-#: ../src/daemon/main.c:858
+#: ../src/daemon/main.c:860
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() falhou."
 
-#: ../src/daemon/main.c:919
+#: ../src/daemon/main.c:921
 msgid "Failed to initialize daemon."
 msgstr "Falha em iniciar o daemon."
 
-#: ../src/daemon/main.c:924
+#: ../src/daemon/main.c:926
 msgid "Daemon startup without any loaded modules, refusing to work."
-msgstr "O Daemon iniciou sem qualquer módulo carregado, recusando-se a trabalhar."
+msgstr ""
+"O Daemon iniciou sem qualquer módulo carregado, recusando-se a trabalhar."
 
-#: ../src/daemon/main.c:929
+#: ../src/daemon/main.c:931
 #, c-format
 msgid "Default sink name (%s) does not exist in name register."
 msgstr "O nome padrão do destino (%s) não existe no registro de nomes."
 
-#: ../src/daemon/main.c:942
+#: ../src/daemon/main.c:944
 msgid "Daemon startup complete."
 msgstr "A partida dos Daemon está completa."
 
-#: ../src/daemon/main.c:948
+#: ../src/daemon/main.c:950
 msgid "Daemon shutdown initiated."
 msgstr "O encerramento do Daemon foi iniciado."
 
-#: ../src/daemon/main.c:969
+#: ../src/daemon/main.c:971
 msgid "Daemon terminated."
 msgstr "Daemon terminado."
 
@@ -406,8 +417,10 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
 "      --check                           Check for a running daemon\n"
 "\n"
@@ -416,24 +429,31 @@ msgid ""
 "  -D, --daemonize[=BOOL]                Daemonize after startup\n"
 "      --fail[=BOOL]                     Quit when startup fails\n"
 "      --high-priority[=BOOL]            Try to set high nice level\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -444,10 +464,12 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -458,53 +480,74 @@ msgstr ""
 "  -h, --help                            Mostra esta ajuda\n"
 "      --version                        Mostra a versão\n"
 "      --dump-conf                       Descarrega a configuração padrão\n"
-"      --dump-modules                   Descarrega a lista de módulos disponíveis\n"
-"      --dump-resample-methods           Descarrega os métodos de reamostragem (resample)\n"
-"      --cleanup-shm                     Limpa os segmentos de memória compartilhados\n"
-"      --start                           Inicia o daemon se ele não estiver em execução\n"
+"      --dump-modules                   Descarrega a lista de módulos "
+"disponíveis\n"
+"      --dump-resample-methods           Descarrega os métodos de "
+"reamostragem (resample)\n"
+"      --cleanup-shm                     Limpa os segmentos de memória "
+"compartilhados\n"
+"      --start                           Inicia o daemon se ele não estiver "
+"em execução\n"
 "  -k  --kill                            Encerra um daemon em execução\n"
 "      --check                           Verifica um daemon em execução\n"
 "\n"
 "OPÇÕES:\n"
-"      --system[=BOOL]                   Executa como uma instância do sistema em escala ampla \n"
-"  -D, --daemonize[=BOOL]                Torna um daemom (daemonize) depois da partida\n"
+"      --system[=BOOL]                   Executa como uma instância do "
+"sistema em escala ampla \n"
+"  -D, --daemonize[=BOOL]                Torna um daemom (daemonize) depois "
+"da partida\n"
 "      --fail[=BOOL]                     Sai quando a partida falha\n"
 "      --high-priority[=BOOL]            Tenta definir um nível alto de nice\n"
 "                                        (disponível apenas, quando SUID ou\n"
 "                                        com RLIMIT_NICE) elevado\n"
-"      --realtime[=BOOL]                 Tenta habilidar o escalonamento em tempo real\n"
-"                                        (disponível apenas como root, quando SUID ou\n"
+"      --realtime[=BOOL]                 Tenta habilidar o escalonamento em "
+"tempo real\n"
+"                                        (disponível apenas como root, quando "
+"SUID ou\n"
 "                                        com  RLIMIT_RTPRIO) elevado\n"
-"      --disallow-module-loading[=BOOL]  Não permite carga/descarga de módulo requerido pelo usuário\n"
+"      --disallow-module-loading[=BOOL]  Não permite carga/descarga de módulo "
+"requerido pelo usuário\n"
 "                                        depois da partida\n"
-"      --disallow-exit[=BOOL]            Não permite saída requisitada pelo usuário\n"
-"      --exit-idle-time=SECS             Termina um daemon quando ocioso e este\n"
+"      --disallow-exit[=BOOL]            Não permite saída requisitada pelo "
+"usuário\n"
+"      --exit-idle-time=SECS             Termina um daemon quando ocioso e "
+"este\n"
 "                                        tempo foi decorrido\n"
-"      --module-idle-time=SECS           Descarrega os modulos autocarregáveis quando ociosos e\n"
+"      --module-idle-time=SECS           Descarrega os modulos "
+"autocarregáveis quando ociosos e\n"
 "                                        tempo foi decorrido\n"
-"      --scache-idle-time=SECS           Descarrega amostras quando ociosas e\n"
+"      --scache-idle-time=SECS           Descarrega amostras quando ociosas "
+"e\n"
 "                                        este tempo tenha passado\n"
-"      --log-level[=LEVEL]               Aumenta ou define o grau de verbosidade\n"
+"      --log-level[=LEVEL]               Aumenta ou define o grau de "
+"verbosidade\n"
 "  -v                                    Aumenta o nível de verbosidade\n"
 "      --log-target={auto,syslog,stderr} Especifica o alvo do log\n"
-"  -p, --dl-search-path=PATH             Define o caminho de busca (search paht)para objetos (plugins)\n"
+"  -p, --dl-search-path=PATH             Define o caminho de busca (search "
+"paht)para objetos (plugins)\n"
 "                                            dinamicamente commpartilhados\n"
-"      --resample-method=METHOD         Usa o método de reamostragem especificado\n"
+"      --resample-method=METHOD         Usa o método de reamostragem "
+"especificado\n"
 "                                        (Veja --dump-resample-methods para\n"
 "                                        valores possíveis)\n"
 "      --use-pid-file[=BOOL]             Cria um arquivo PID file\n"
-"      --no-cpu-limit[=BOOL]            Não instala um limitador de carga de CPU load em\n"
+"      --no-cpu-limit[=BOOL]            Não instala um limitador de carga de "
+"CPU load em\n"
 "                                        plataformas que o suportem.\n"
-"      --disable-shm[=BOOL]              Desabilita o suporte a memória compartilhada.\n"
+"      --disable-shm[=BOOL]              Desabilita o suporte a memória "
+"compartilhada.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Carrega um plugin especificado com\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Carrega um plugin especificado "
+"com\n"
 "                                        o argumento especificado\n"
 "  -F, --file=FILENAME                  Executa o script especificado\n"
-"  -C                                    Abre uma linha de comando no TTY em execução\n"
+"  -C                                    Abre uma linha de comando no TTY em "
+"execução\n"
 "                                       depois da partida\n"
 "\n"
-"  -n                                    Não carrega o arquivo de script padrão\n"
+"  -n                                    Não carrega o arquivo de script "
+"padrão\n"
 
 #: ../src/daemon/cmdline.c:245
 msgid "--daemonize expects boolean argument"
@@ -515,8 +558,12 @@ msgid "--fail expects boolean argument"
 msgstr "--fail espera argumento booleano"
 
 #: ../src/daemon/cmdline.c:262
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
-msgstr "--log-level espera um argumento em nível de log  (seja numérico na faixa de 0..4 seja algum entre debug, info, notice, warn, error)."
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
+msgstr ""
+"--log-level espera um argumento em nível de log  (seja numérico na faixa de "
+"0..4 seja algum entre debug, info, notice, warn, error)."
 
 #: ../src/daemon/cmdline.c:274
 msgid "--high-priority expects boolean argument"
@@ -599,76 +646,76 @@ msgstr "Carrega uma vez: %s\n"
 msgid "Path: %s\n"
 msgstr "Caminho: %s\n"
 
-#: ../src/daemon/daemon-conf.c:204
+#: ../src/daemon/daemon-conf.c:205
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr "[%s:%u] Alvo do log inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:220
+#: ../src/daemon/daemon-conf.c:221
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr "[%s:%u] Nível de log inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:236
+#: ../src/daemon/daemon-conf.c:237
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr "[%s:%u] Método de reamostragem inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:259
+#: ../src/daemon/daemon-conf.c:260
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr "[%s:%u] rlimit inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:266
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr "[%s:%u] rlimit não tem suporte nessa plataforma."
 
-#: ../src/daemon/daemon-conf.c:282
+#: ../src/daemon/daemon-conf.c:283
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr "[%s:%u] Formato de amostragem inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:300
+#: ../src/daemon/daemon-conf.c:301
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr "[%s:%u] Taxa de amostragem inválida '%s'."
 
-#: ../src/daemon/daemon-conf.c:318
+#: ../src/daemon/daemon-conf.c:319
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr "[%s:%u] Canais de amostragem inválidos'%s'."
 
-#: ../src/daemon/daemon-conf.c:336
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr "[%s:%u] Números de fragmentos inválidos '%s'."
 
-#: ../src/daemon/daemon-conf.c:354
+#: ../src/daemon/daemon-conf.c:355
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr "[%s:%u] Tamanho de fragmentos inválido '%s'."
 
-#: ../src/daemon/daemon-conf.c:372
+#: ../src/daemon/daemon-conf.c:373
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr "[%s:%u] Número de nice inválido'%s'."
 
-#: ../src/daemon/daemon-conf.c:567
+#: ../src/daemon/daemon-conf.c:570
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Falha em abrir o arquivo de configuração: %s"
 
-#: ../src/daemon/daemon-conf.c:641
+#: ../src/daemon/daemon-conf.c:644
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr "### Lido do arquivo de configuração: %s ###\n"
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
 msgid "Dropping root priviliges."
 msgstr "Descartando os privilégios de root."
 
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr "As capacidades foram limitadas com sucesso para CAP_SYS_NICE."
 
@@ -876,6 +923,12 @@ msgstr "Posterior Superior Esquerdo"
 msgid "Top Rear Right"
 msgstr "Posterior Superior Direito"
 
+#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
+#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+#, fuzzy
+msgid "(invalid)"
+msgstr "Inválido"
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr "OK"
@@ -964,12 +1017,7 @@ msgstr "Código de erro desconhecido"
 msgid "No such extension"
 msgstr "Não existe tal extensão"
 
-#: ../src/pulse/sample.c:134
-msgid "Invalid"
-msgstr "Inválido"
-
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() falhou"
 
@@ -977,7 +1025,7 @@ msgstr "XOpenDisplay() falhou"
 msgid "Failed to parse cookie data"
 msgstr "Falhou ao analisar os dados do cookie"
 
-#: ../src/pulse/client-conf.c:117
+#: ../src/pulse/client-conf.c:120
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Falha em abrir o arquivo de configuração '%s': %s"
@@ -1110,28 +1158,23 @@ msgstr "pa_stream_connect_playback() falhou: %s\n"
 msgid "pa_stream_connect_record() failed: %s\n"
 msgstr "pa_stream_connect_record() falhou: %s\n"
 
-#: ../src/utils/pacat.c:307
-#: ../src/utils/pasuspender.c:159
-#: ../src/utils/pactl.c:666
-#: ../src/utils/paplay.c:183
+#: ../src/utils/pacat.c:307 ../src/utils/pasuspender.c:159
+#: ../src/utils/pactl.c:666 ../src/utils/paplay.c:183
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Falha na conexão: %s\n"
 
-#: ../src/utils/pacat.c:328
-#: ../src/utils/paplay.c:75
+#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75
 #, c-format
 msgid "Failed to drain stream: %s\n"
 msgstr "Falha em drenar o fluxo: %s\n"
 
-#: ../src/utils/pacat.c:333
-#: ../src/utils/paplay.c:80
+#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80
 #, c-format
 msgid "Playback stream drained.\n"
 msgstr "Drenado o fluxo de playback.\n"
 
-#: ../src/utils/pacat.c:343
-#: ../src/utils/paplay.c:92
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
 #, c-format
 msgid "Draining connection to server.\n"
 msgstr "Drenando a conexão par ao servidor.\n"
@@ -1189,27 +1232,44 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(defaults to s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
 msgstr ""
 "%s [opções]\n"
 "\n"
@@ -1224,23 +1284,37 @@ msgstr ""
 "  -s, --server=SERVER                   Nome do servidor a ser conectado\n"
 "  -d, --device=DEVICE                   O nome do destino/fonte a conectar\n"
 "  -n, --client-name=NAME                Como chamar o cliente no servidor\n"
-"      --stream-name=NAME               Como chamar este fluxo no servidorn      --volume=VOLUME                   Especifica a faixa (linear) inicial de volume no intervalo 0...65536\n"
-"      --rate=SAMPLERATE                 Taxa de amostragem em Hz (o padrão é 44100)\n"
-"      --format=SAMPLEFORMAT             Tipo de amostragem, um de s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw, s32le, s32be (o padrão é s16ne)\n"
-"      --channels=CHANNELS               O número de canais, 1 para mono, 2 para estéreo\n"
+"      --stream-name=NAME               Como chamar este fluxo no "
+"servidorn      --volume=VOLUME                   Especifica a faixa (linear) "
+"inicial de volume no intervalo 0...65536\n"
+"      --rate=SAMPLERATE                 Taxa de amostragem em Hz (o padrão é "
+"44100)\n"
+"      --format=SAMPLEFORMAT             Tipo de amostragem, um de s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(o padrão é s16ne)\n"
+"      --channels=CHANNELS               O número de canais, 1 para mono, 2 "
+"para estéreo\n"
 "                                        (o padrão é 2)\n"
-"      --channel-map=CHANNELMAP          Mapeamento de canais a ser usando em lugar do padrão\n"
-"      --fix-format                      Obtém o formato da amostragem do destino onde o fluxo\n"
+"      --channel-map=CHANNELMAP          Mapeamento de canais a ser usando em "
+"lugar do padrão\n"
+"      --fix-format                      Obtém o formato da amostragem do "
+"destino onde o fluxo\n"
 " está sendo conectado.\n"
-"            --fix-rate                        Obtém o taxa de amostragem do destino onde o fluxo está\n"
+"            --fix-rate                        Obtém o taxa de amostragem do "
+"destino onde o fluxo está\n"
 "                                        sendo conectado.\n"
-"      --fix-channels                    Obtém o número de canais e o mapa de canais\n"
-"                                      do destino onde o fluxo está sendo conectado.\n"
+"      --fix-channels                    Obtém o número de canais e o mapa de "
+"canais\n"
+"                                      do destino onde o fluxo está sendo "
+"conectado.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
 
 #: ../src/utils/pacat.c:591
 #, c-format
@@ -1306,10 +1380,8 @@ msgstr "dup2(): %s\n"
 msgid "Too many arguments.\n"
 msgstr "Argumentos em excesso.\n"
 
-#: ../src/utils/pacat.c:742
-#: ../src/utils/pasuspender.c:280
-#: ../src/utils/pactl.c:909
-#: ../src/utils/paplay.c:381
+#: ../src/utils/pacat.c:742 ../src/utils/pasuspender.c:280
+#: ../src/utils/pactl.c:909 ../src/utils/paplay.c:381
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
 msgstr "pa_mainloop_new() falhou.\n"
@@ -1319,10 +1391,8 @@ msgstr "pa_mainloop_new() falhou.\n"
 msgid "io_new() failed.\n"
 msgstr "io_new() falhou.\n"
 
-#: ../src/utils/pacat.c:769
-#: ../src/utils/pasuspender.c:293
-#: ../src/utils/pactl.c:923
-#: ../src/utils/paplay.c:396
+#: ../src/utils/pacat.c:769 ../src/utils/pasuspender.c:293
+#: ../src/utils/pactl.c:923 ../src/utils/paplay.c:396
 #, c-format
 msgid "pa_context_new() failed.\n"
 msgstr "pa_context_new() falhou.\n"
@@ -1337,10 +1407,8 @@ msgstr "pa_context_new() falhou: %s"
 msgid "time_new() failed.\n"
 msgstr "time_new() falhou.\n"
 
-#: ../src/utils/pacat.c:795
-#: ../src/utils/pasuspender.c:301
-#: ../src/utils/pactl.c:931
-#: ../src/utils/paplay.c:407
+#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301
+#: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() falhou.\n"
@@ -1368,10 +1436,11 @@ msgstr "Falha ao prosseguir: %s\n"
 #: ../src/utils/pasuspender.c:147
 #, c-format
 msgid "WARNING: Sound server is not local, not suspending.\n"
-msgstr "AVISO: O servidor de som não é local, Sound server is not local, não está em suspenso.\n"
+msgstr ""
+"AVISO: O servidor de som não é local, Sound server is not local, não está em "
+"suspenso.\n"
 
-#: ../src/utils/pasuspender.c:176
-#: ../src/utils/pactl.c:672
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
 #: ../src/utils/paplay.c:191
 #, c-format
 msgid "Got SIGINT, exiting.\n"
@@ -1389,7 +1458,8 @@ msgid ""
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 "%s [options] ... \n"
@@ -1490,8 +1560,7 @@ msgstr ""
 "Propriedades:\n"
 "%s"
 
-#: ../src/utils/pactl.c:193
-#: ../src/utils/pactl.c:371
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
 msgid "muted"
 msgstr "mudo"
 
@@ -1529,18 +1598,10 @@ msgstr ""
 "Propriedades:\n"
 "%s"
 
-#: ../src/utils/pactl.c:246
-#: ../src/utils/pactl.c:289
-#: ../src/utils/pactl.c:322
-#: ../src/utils/pactl.c:366
-#: ../src/utils/pactl.c:367
-#: ../src/utils/pactl.c:374
-#: ../src/utils/pactl.c:418
-#: ../src/utils/pactl.c:419
-#: ../src/utils/pactl.c:425
-#: ../src/utils/pactl.c:468
-#: ../src/utils/pactl.c:469
-#: ../src/utils/pactl.c:473
+#: ../src/utils/pactl.c:246 ../src/utils/pactl.c:289 ../src/utils/pactl.c:322
+#: ../src/utils/pactl.c:366 ../src/utils/pactl.c:367 ../src/utils/pactl.c:374
+#: ../src/utils/pactl.c:418 ../src/utils/pactl.c:419 ../src/utils/pactl.c:425
+#: ../src/utils/pactl.c:468 ../src/utils/pactl.c:469 ../src/utils/pactl.c:473
 msgid "n/a"
 msgstr "n/a"
 
@@ -1714,8 +1775,7 @@ msgstr "destino"
 msgid "source"
 msgstr "fonte"
 
-#: ../src/utils/pactl.c:511
-#: ../src/utils/pactl.c:521
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
 #, c-format
 msgid "Failure: %s\n"
 msgstr "Falha: %s\n"
@@ -1749,8 +1809,10 @@ msgid ""
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 msgstr ""
 "%s [options] stat\n"
 "%s [options] list\n"
@@ -1769,7 +1831,8 @@ msgstr ""
 "      --version                        Mostra a versão\n"
 "\n"
 "  -s, --server=SERVER                   O nome do servidor a ser conectado\n"
-"  -n, --client-name=NAME                Como chamar este cliente no servidor \n"
+"  -n, --client-name=NAME                Como chamar este cliente no "
+"servidor \n"
 
 #: ../src/utils/pactl.c:729
 #, c-format
@@ -1805,7 +1868,8 @@ msgstr "Você deve especificar um nome da amostra para ser removida\n"
 #: ../src/utils/pactl.c:822
 #, c-format
 msgid "You have to specify a sink input index and a sink\n"
-msgstr "Você tem que especificar a entrada para o destino (sink) e um destino(sink)\n"
+msgstr ""
+"Você tem que especificar a entrada para o destino (sink) e um destino(sink)\n"
 
 #: ../src/utils/pactl.c:831
 #, c-format
@@ -1824,13 +1888,21 @@ msgstr "Você deve especificar um índice de um módulo\n"
 
 #: ../src/utils/pactl.c:875
 #, c-format
-msgid "You may not specify more than one sink. You have to specify at least one boolean value.\n"
-msgstr "Você não pode especificar mais de um destino. Pelo menos um valor booleano deve ser especificado.\n"
+msgid ""
+"You may not specify more than one sink. You have to specify at least one "
+"boolean value.\n"
+msgstr ""
+"Você não pode especificar mais de um destino. Pelo menos um valor booleano "
+"deve ser especificado.\n"
 
 #: ../src/utils/pactl.c:888
 #, c-format
-msgid "You may not specify more than one source. You have to specify at least one boolean value.\n"
-msgstr "Você não pode especificar mais de uma fonte. Pelo menos um valor booleano deve ser especificado.\n"
+msgid ""
+"You may not specify more than one source. You have to specify at least one "
+"boolean value.\n"
+msgstr ""
+"Você não pode especificar mais de uma fonte. Pelo menos um valor booleano "
+"deve ser especificado.\n"
 
 #: ../src/utils/pactl.c:904
 #, c-format
@@ -1844,14 +1916,17 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 "%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n"
 "\n"
-" -d    Mostra os dados atuais do PulseAudio associados ao display X11 (padrão)\n"
+" -d    Mostra os dados atuais do PulseAudio associados ao display X11 "
+"(padrão)\n"
 " -e    Exporta os dados locais do PulseAudio para um display X11 \n"
-" -i     Importa os dados do PulseAudio de um display X11 para as variáveis de ambiente locais e para o arquivo de cookie.\n"
+" -i     Importa os dados do PulseAudio de um display X11 para as variáveis "
+"de ambiente locais e para o arquivo de cookie.\n"
 " -r    Remove os dados do PulseAudio do display X11\n"
 
 #: ../src/utils/pax11publish.c:94
@@ -1937,14 +2012,12 @@ msgstr "Daemon não responde."
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124
-#: ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153
-#: ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
@@ -1974,11 +2047,15 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operation\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "  -d, --device=DEVICE                   The name of the sink to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
 "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 msgstr ""
 "%s [options] [FILE]\n"
@@ -1990,9 +2067,11 @@ msgstr ""
 "\n"
 "  -s, --server=SERVER                   O nome do servidor a ser conectado\n"
 "  -d, --device=DEVICE                   O nome do destino a ser conectado\n"
-"  -n, --client-name=NAME                Como chamar este cliente no servidor\n"
+"  -n, --client-name=NAME                Como chamar este cliente no "
+"servidor\n"
 "      --stream-name=NAME                Como chamar este fluxo no servidor\n"
-"      --volume=VOLUME                   Especifica o volume inicial (linear) no intervalo 0...65536\n"
+"      --volume=VOLUME                   Especifica o volume inicial (linear) "
+"no intervalo 0...65536\n"
 "      --channel-map=CHANNELMAP          Define o mapa do canal para uso\n"
 
 #: ../src/utils/paplay.c:255
@@ -2026,11 +2105,26 @@ msgstr "O mapa dos canais não coincide com o arquivo.\n"
 msgid "Using sample spec '%s'\n"
 msgstr "Usando a especificação da amostragem '%s'\n"
 
-#: ../src/pulsecore/lock-autospawn.c:126
-#: ../src/pulsecore/lock-autospawn.c:207
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
 msgid "Cannot access autospawn lock."
 msgstr "Não foi possível acessar a trava de autogeração."
 
+#~ msgid ""
+#~ "' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
+#~ "For enabling real-time scheduling please acquire the appropriate "
+#~ "PolicyKit priviliges, or become a member of '"
+#~ msgstr ""
+#~ "' e o PolicyKit recusa-nos a garantia de privilégios. Retirando o SUID "
+#~ "outra vez.\n"
+#~ " Para habilitar o escalonamento em tempo real, por favo, adquira os "
+#~ "privilégios adequados pelo PolicyKit, ou torne-se membro do'"
+
+#~ msgid ""
+#~ "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this "
+#~ "user."
+#~ msgstr ""
+#~ "', ou eleve o RLIMIT_NICE/RLIMIT_RTPRIO dos limites do recurso para este "
+#~ "usuário."
+
 #~ msgid "socketpair(): %s"
 #~ msgstr "socketpair(): %s"
-
index 11f6e13c3a5041dd4bb644e84b09b7ea2d7bb6bd..772e155213bba8b6760e082ec99572a02c0f4b5b 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: pulseaudio\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-09-04 19:30+0000\n"
+"POT-Creation-Date: 2008-10-07 21:03+0200\n"
 "PO-Revision-Date: 2008-09-05 18:24+0100\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -15,8 +15,7 @@ msgstr ""
 "Content-Type: text/plain; charset=utf-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../src/daemon/ltdl-bind-now.c:177
-#: ../src/daemon/ltdl-bind-now.c:197
+#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
 msgid "Failed to add bind-now-loader."
 msgstr ""
 
@@ -112,8 +111,7 @@ msgstr ""
 msgid "Home directory of user '%s' is not '%s', ignoring."
 msgstr "Hemkatalogen för användaren \"%s\" är inte \"%s\", ignorerar."
 
-#: ../src/daemon/main.c:201
-#: ../src/daemon/main.c:206
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
 #, c-format
 msgid "Failed to create '%s': %s"
 msgstr "Misslyckades med att skapa \"%s\": %s"
@@ -178,22 +176,14 @@ msgstr ""
 
 #: ../src/daemon/main.c:479
 msgid ""
-"Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary priviliges:\n"
+"Called SUID root and real-time/high-priority scheduling was requested in the "
+"configuration. However, we lack the necessary priviliges:\n"
 "We are not in group '"
 msgstr ""
 
-#: ../src/daemon/main.c:480
-msgid ""
-"' and PolicyKit refuse to grant us priviliges. Dropping SUID again.\n"
-"For enabling real-time scheduling please acquire the appropriate PolicyKit priviliges, or become a member of '"
-msgstr ""
-
-#: ../src/daemon/main.c:481
-msgid "', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."
-msgstr ""
-
 #: ../src/daemon/main.c:497
-msgid "High-priority scheduling enabled in configuration but not allowed by policy."
+msgid ""
+"High-priority scheduling enabled in configuration but not allowed by policy."
 msgstr ""
 
 #: ../src/daemon/main.c:522
@@ -210,7 +200,8 @@ msgid "Giving up CAP_NICE"
 msgstr ""
 
 #: ../src/daemon/main.c:539
-msgid "Real-time scheduling enabled in configuration but not allowed by policy."
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
 msgstr ""
 
 #: ../src/daemon/main.c:597
@@ -228,8 +219,12 @@ msgid "Failed to kill daemon: %s"
 msgstr ""
 
 #: ../src/daemon/main.c:627
-msgid "This program is not intended to be run as root (unless --system is specified)."
-msgstr "Detta program är inte tänkt att köras som root (såvida inte --system har angivits)."
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Detta program är inte tänkt att köras som root (såvida inte --system har "
+"angivits)."
 
 #: ../src/daemon/main.c:629
 msgid "Root priviliges required."
@@ -289,92 +284,109 @@ msgstr "Detta är PulseAudio %s"
 
 #: ../src/daemon/main.c:781
 #, c-format
+msgid "Compilation host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:782
+#, c-format
 msgid "Compilation CFLAGS: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:784
+#: ../src/daemon/main.c:785
+#, c-format
+msgid "Running on host: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:788
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr ""
+
+#: ../src/daemon/main.c:791
 msgid "Compiled with Valgrind support: yes"
 msgstr ""
 
-#: ../src/daemon/main.c:786
+#: ../src/daemon/main.c:793
 msgid "Compiled with Valgrind support: no"
 msgstr ""
 
-#: ../src/daemon/main.c:790
-msgid "Optimized build: yes"
+#: ../src/daemon/main.c:796
+#, c-format
+msgid "Running in valgrind mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:792
-msgid "Optimized build: no"
+#: ../src/daemon/main.c:799
+msgid "Optimized build: yes"
 msgstr ""
 
-#: ../src/daemon/main.c:795
-#, c-format
-msgid "Page size is %lu bytes"
+#: ../src/daemon/main.c:801
+msgid "Optimized build: no"
 msgstr ""
 
-#: ../src/daemon/main.c:798
+#: ../src/daemon/main.c:805
 msgid "Failed to get machine ID"
 msgstr ""
 
-#: ../src/daemon/main.c:801
+#: ../src/daemon/main.c:808
 #, c-format
 msgid "Machine ID is %s."
 msgstr ""
 
-#: ../src/daemon/main.c:806
+#: ../src/daemon/main.c:813
 #, c-format
 msgid "Using runtime directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:811
+#: ../src/daemon/main.c:818
 #, c-format
 msgid "Using state directory %s."
 msgstr ""
 
-#: ../src/daemon/main.c:814
+#: ../src/daemon/main.c:821
 #, c-format
 msgid "Running in system mode: %s"
 msgstr ""
 
-#: ../src/daemon/main.c:829
+#: ../src/daemon/main.c:836
 msgid "pa_pid_file_create() failed."
 msgstr "pa_pid_file_create() misslyckades."
 
-#: ../src/daemon/main.c:841
+#: ../src/daemon/main.c:848
 msgid "Fresh high-resolution timers available! Bon appetit!"
 msgstr ""
 
-#: ../src/daemon/main.c:843
-msgid "Dude, your kernel stinks! The chef's recommendation today is Linux with high-resolution timers enabled!"
+#: ../src/daemon/main.c:850
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
 msgstr ""
 
-#: ../src/daemon/main.c:853
+#: ../src/daemon/main.c:860
 msgid "pa_core_new() failed."
 msgstr "pa_core_new() misslyckades."
 
-#: ../src/daemon/main.c:913
+#: ../src/daemon/main.c:921
 msgid "Failed to initialize daemon."
 msgstr ""
 
-#: ../src/daemon/main.c:918
+#: ../src/daemon/main.c:926
 msgid "Daemon startup without any loaded modules, refusing to work."
 msgstr ""
 
-#: ../src/daemon/main.c:923
+#: ../src/daemon/main.c:931
 #, c-format
 msgid "Default sink name (%s) does not exist in name register."
 msgstr ""
 
-#: ../src/daemon/main.c:936
+#: ../src/daemon/main.c:944
 msgid "Daemon startup complete."
 msgstr ""
 
-#: ../src/daemon/main.c:942
+#: ../src/daemon/main.c:950
 msgid "Daemon shutdown initiated."
 msgstr ""
 
-#: ../src/daemon/main.c:963
+#: ../src/daemon/main.c:971
 msgid "Daemon terminated."
 msgstr ""
 
@@ -389,8 +401,10 @@ msgid ""
 "      --dump-conf                       Dump default configuration\n"
 "      --dump-modules                    Dump list of available modules\n"
 "      --dump-resample-methods           Dump available resample methods\n"
-"      --cleanup-shm                     Cleanup stale shared memory segments\n"
-"      --start                           Start the daemon if it is not running\n"
+"      --cleanup-shm                     Cleanup stale shared memory "
+"segments\n"
+"      --start                           Start the daemon if it is not "
+"running\n"
 "  -k  --kill                            Kill a running daemon\n"
 "      --check                           Check for a running daemon\n"
 "\n"
@@ -399,24 +413,31 @@ msgid ""
 "  -D, --daemonize[=BOOL]                Daemonize after startup\n"
 "      --fail[=BOOL]                     Quit when startup fails\n"
 "      --high-priority[=BOOL]            Try to set high nice level\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_NICE)\n"
 "      --realtime[=BOOL]                 Try to enable realtime scheduling\n"
-"                                        (only available as root, when SUID or\n"
+"                                        (only available as root, when SUID "
+"or\n"
 "                                        with elevated RLIMIT_RTPRIO)\n"
-"      --disallow-module-loading[=BOOL]  Disallow module user requested module\n"
+"      --disallow-module-loading[=BOOL]  Disallow module user requested "
+"module\n"
 "                                        loading/unloading after startup\n"
 "      --disallow-exit[=BOOL]            Disallow user requested exit\n"
-"      --exit-idle-time=SECS             Terminate the daemon when idle and this\n"
+"      --exit-idle-time=SECS             Terminate the daemon when idle and "
+"this\n"
 "                                        time passed\n"
-"      --module-idle-time=SECS           Unload autoloaded modules when idle and\n"
+"      --module-idle-time=SECS           Unload autoloaded modules when idle "
+"and\n"
 "                                        this time passed\n"
-"      --scache-idle-time=SECS           Unload autoloaded samples when idle and\n"
+"      --scache-idle-time=SECS           Unload autoloaded samples when idle "
+"and\n"
 "                                        this time passed\n"
 "      --log-level[=LEVEL]               Increase or set verbosity level\n"
 "  -v                                    Increase the verbosity level\n"
 "      --log-target={auto,syslog,stderr} Specify the log target\n"
-"  -p, --dl-search-path=PATH             Set the search path for dynamic shared\n"
+"  -p, --dl-search-path=PATH             Set the search path for dynamic "
+"shared\n"
 "                                        objects (plugins)\n"
 "      --resample-method=METHOD          Use the specified resampling method\n"
 "                                        (See --dump-resample-methods for\n"
@@ -427,10 +448,12 @@ msgid ""
 "      --disable-shm[=BOOL]              Disable shared memory support.\n"
 "\n"
 "STARTUP SCRIPT:\n"
-"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module with\n"
+"  -L, --load=\"MODULE ARGUMENTS\"         Load the specified plugin module "
+"with\n"
 "                                        the specified argument\n"
 "  -F, --file=FILENAME                   Run the specified script\n"
-"  -C                                    Open a command line on the running TTY\n"
+"  -C                                    Open a command line on the running "
+"TTY\n"
 "                                        after startup\n"
 "\n"
 "  -n                                    Don't load default script file\n"
@@ -445,7 +468,9 @@ msgid "--fail expects boolean argument"
 msgstr "--fail förväntar sig ett booleskt argument"
 
 #: ../src/daemon/cmdline.c:262
-msgid "--log-level expects log level argument (either numeric in range 0..4 or one of debug, info, notice, warn, error)."
+msgid ""
+"--log-level expects log level argument (either numeric in range 0..4 or one "
+"of debug, info, notice, warn, error)."
 msgstr ""
 
 #: ../src/daemon/cmdline.c:274
@@ -529,76 +554,76 @@ msgstr ""
 msgid "Path: %s\n"
 msgstr "Sökväg: %s\n"
 
-#: ../src/daemon/daemon-conf.c:203
+#: ../src/daemon/daemon-conf.c:205
 #, c-format
 msgid "[%s:%u] Invalid log target '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:219
+#: ../src/daemon/daemon-conf.c:221
 #, c-format
 msgid "[%s:%u] Invalid log level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:235
+#: ../src/daemon/daemon-conf.c:237
 #, c-format
 msgid "[%s:%u] Invalid resample method '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:258
+#: ../src/daemon/daemon-conf.c:260
 #, c-format
 msgid "[%s:%u] Invalid rlimit '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:265
+#: ../src/daemon/daemon-conf.c:267
 #, c-format
 msgid "[%s:%u] rlimit not supported on this platform."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:281
+#: ../src/daemon/daemon-conf.c:283
 #, c-format
 msgid "[%s:%u] Invalid sample format '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:299
+#: ../src/daemon/daemon-conf.c:301
 #, c-format
 msgid "[%s:%u] Invalid sample rate '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:317
+#: ../src/daemon/daemon-conf.c:319
 #, c-format
 msgid "[%s:%u] Invalid sample channels '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:335
+#: ../src/daemon/daemon-conf.c:337
 #, c-format
 msgid "[%s:%u] Invalid number of fragments '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:353
+#: ../src/daemon/daemon-conf.c:355
 #, c-format
 msgid "[%s:%u] Invalid fragment size '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:371
+#: ../src/daemon/daemon-conf.c:373
 #, c-format
 msgid "[%s:%u] Invalid nice level '%s'."
 msgstr ""
 
-#: ../src/daemon/daemon-conf.c:564
+#: ../src/daemon/daemon-conf.c:570
 #, c-format
 msgid "Failed to open configuration file: %s"
 msgstr "Misslyckades med att öppna konfigurationsfil: %s"
 
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:644
 #, c-format
 msgid "### Read from configuration file: %s ###\n"
 msgstr ""
 
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
 msgid "Dropping root priviliges."
 msgstr "Släpper root-behörighet."
 
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
 msgid "Limited capabilities successfully to CAP_SYS_NICE."
 msgstr ""
 
@@ -806,6 +831,12 @@ msgstr ""
 msgid "Top Rear Right"
 msgstr ""
 
+#: ../src/pulse/channelmap.c:472 ../src/pulse/sample.c:144
+#: ../src/pulse/volume.c:163 ../src/pulse/volume.c:194
+#, fuzzy
+msgid "(invalid)"
+msgstr "Ogiltig"
+
 #: ../src/pulse/error.c:43
 msgid "OK"
 msgstr "OK"
@@ -894,12 +925,7 @@ msgstr "Okänd felkod"
 msgid "No such extension"
 msgstr ""
 
-#: ../src/pulse/sample.c:134
-msgid "Invalid"
-msgstr "Ogiltig"
-
-#: ../src/pulse/client-conf-x11.c:55
-#: ../src/utils/pax11publish.c:100
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
 msgid "XOpenDisplay() failed"
 msgstr "XOpenDisplay() misslyckades"
 
@@ -907,31 +933,26 @@ msgstr "XOpenDisplay() misslyckades"
 msgid "Failed to parse cookie data"
 msgstr ""
 
-#: ../src/pulse/client-conf.c:117
+#: ../src/pulse/client-conf.c:120
 #, c-format
 msgid "Failed to open configuration file '%s': %s"
 msgstr "Misslyckades med att öppna konfigurationsfilen \"%s\": %s"
 
-#: ../src/pulse/context.c:542
+#: ../src/pulse/context.c:516
 msgid "No cookie loaded. Attempting to connect without."
 msgstr ""
 
-#: ../src/pulse/context.c:596
-#, c-format
-msgid "socketpair(): %s"
-msgstr "socketpair(): %s"
-
-#: ../src/pulse/context.c:610
+#: ../src/pulse/context.c:642
 #, c-format
 msgid "fork(): %s"
 msgstr "fork(): %s"
 
-#: ../src/pulse/context.c:673
+#: ../src/pulse/context.c:695
 #, c-format
 msgid "waitpid(): %s"
 msgstr "waitpid(): %s"
 
-#: ../src/pulse/context.c:1354
+#: ../src/pulse/context.c:1256
 #, c-format
 msgid "Received message for unknown extension '%s'"
 msgstr ""
@@ -1045,28 +1066,23 @@ msgstr "pa_stream_connect_playback() misslyckades: %s\n"
 msgid "pa_stream_connect_record() failed: %s\n"
 msgstr "pa_stream_connect_record() misslyckades: %s\n"
 
-#: ../src/utils/pacat.c:307
-#: ../src/utils/pasuspender.c:159
-#: ../src/utils/pactl.c:666
-#: ../src/utils/paplay.c:183
+#: ../src/utils/pacat.c:307 ../src/utils/pasuspender.c:159
+#: ../src/utils/pactl.c:666 ../src/utils/paplay.c:183
 #, c-format
 msgid "Connection failure: %s\n"
 msgstr "Anslutningsfel: %s\n"
 
-#: ../src/utils/pacat.c:328
-#: ../src/utils/paplay.c:75
+#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75
 #, c-format
 msgid "Failed to drain stream: %s\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:333
-#: ../src/utils/paplay.c:80
+#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80
 #, c-format
 msgid "Playback stream drained.\n"
 msgstr ""
 
-#: ../src/utils/pacat.c:343
-#: ../src/utils/paplay.c:92
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
 #, c-format
 msgid "Draining connection to server.\n"
 msgstr ""
@@ -1124,27 +1140,44 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operations\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -d, --device=DEVICE                   The name of the sink/source to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
-"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to 44100)\n"
-"      --format=SAMPLEFORMAT             The sample type, one of s16le, s16be, u8, float32le,\n"
-"                                        float32be, ulaw, alaw (defaults to s16ne)\n"
-"      --channels=CHANNELS               The number of channels, 1 for mono, 2 for stereo\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -d, --device=DEVICE                   The name of the sink/source to "
+"connect to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
+"      --rate=SAMPLERATE                 The sample rate in Hz (defaults to "
+"44100)\n"
+"      --format=SAMPLEFORMAT             The sample type, one of s16le, "
+"s16be, u8, float32le,\n"
+"                                        float32be, ulaw, alaw, s32le, s32be "
+"(defaults to s16ne)\n"
+"      --channels=CHANNELS               The number of channels, 1 for mono, "
+"2 for stereo\n"
 "                                        (defaults to 2)\n"
-"      --channel-map=CHANNELMAP          Channel map to use instead of the default\n"
-"      --fix-format                      Take the sample format from the sink the stream is\n"
+"      --channel-map=CHANNELMAP          Channel map to use instead of the "
+"default\n"
+"      --fix-format                      Take the sample format from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-rate                        Take the sampling rate from the sink the stream is\n"
+"      --fix-rate                        Take the sampling rate from the sink "
+"the stream is\n"
 "                                        being connected to.\n"
-"      --fix-channels                    Take the number of channels and the channel map\n"
-"                                        from the sink the stream is being connected to.\n"
+"      --fix-channels                    Take the number of channels and the "
+"channel map\n"
+"                                        from the sink the stream is being "
+"connected to.\n"
 "      --no-remix                        Don't upmix or downmix channels.\n"
-"      --no-remap                        Map channels by index instead of name.\n"
-"      --latency=BYTES                   Request the specified latency in bytes.\n"
-"      --process-time=BYTES              Request the specified process time per request in bytes.\n"
+"      --no-remap                        Map channels by index instead of "
+"name.\n"
+"      --latency=BYTES                   Request the specified latency in "
+"bytes.\n"
+"      --process-time=BYTES              Request the specified process time "
+"per request in bytes.\n"
 msgstr ""
 
 #: ../src/utils/pacat.c:591
@@ -1208,10 +1241,8 @@ msgstr "dup2(): %s\n"
 msgid "Too many arguments.\n"
 msgstr "För många argument.\n"
 
-#: ../src/utils/pacat.c:742
-#: ../src/utils/pasuspender.c:280
-#: ../src/utils/pactl.c:909
-#: ../src/utils/paplay.c:381
+#: ../src/utils/pacat.c:742 ../src/utils/pasuspender.c:280
+#: ../src/utils/pactl.c:909 ../src/utils/paplay.c:381
 #, c-format
 msgid "pa_mainloop_new() failed.\n"
 msgstr "pa_mainloop_new() misslyckades.\n"
@@ -1221,23 +1252,24 @@ msgstr "pa_mainloop_new() misslyckades.\n"
 msgid "io_new() failed.\n"
 msgstr "io_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:769
-#: ../src/utils/pasuspender.c:293
-#: ../src/utils/pactl.c:923
-#: ../src/utils/paplay.c:396
+#: ../src/utils/pacat.c:769 ../src/utils/pasuspender.c:293
+#: ../src/utils/pactl.c:923 ../src/utils/paplay.c:396
 #, c-format
 msgid "pa_context_new() failed.\n"
 msgstr "pa_context_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:785
+#: ../src/utils/pacat.c:777
+#, fuzzy, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_new() misslyckades.\n"
+
+#: ../src/utils/pacat.c:788
 #, c-format
 msgid "time_new() failed.\n"
 msgstr "time_new() misslyckades.\n"
 
-#: ../src/utils/pacat.c:792
-#: ../src/utils/pasuspender.c:301
-#: ../src/utils/pactl.c:931
-#: ../src/utils/paplay.c:407
+#: ../src/utils/pacat.c:795 ../src/utils/pasuspender.c:301
+#: ../src/utils/pactl.c:931 ../src/utils/paplay.c:407
 #, c-format
 msgid "pa_mainloop_run() failed.\n"
 msgstr "pa_mainloop_run() misslyckades.\n"
@@ -1267,8 +1299,7 @@ msgstr ""
 msgid "WARNING: Sound server is not local, not suspending.\n"
 msgstr ""
 
-#: ../src/utils/pasuspender.c:176
-#: ../src/utils/pactl.c:672
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
 #: ../src/utils/paplay.c:191
 #, c-format
 msgid "Got SIGINT, exiting.\n"
@@ -1286,7 +1317,8 @@ msgid ""
 "\n"
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "\n"
 msgstr ""
 
@@ -1361,8 +1393,7 @@ msgid ""
 "%s"
 msgstr ""
 
-#: ../src/utils/pactl.c:193
-#: ../src/utils/pactl.c:371
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
 msgid "muted"
 msgstr "tystad"
 
@@ -1388,18 +1419,10 @@ msgid ""
 "%s"
 msgstr ""
 
-#: ../src/utils/pactl.c:246
-#: ../src/utils/pactl.c:289
-#: ../src/utils/pactl.c:322
-#: ../src/utils/pactl.c:366
-#: ../src/utils/pactl.c:367
-#: ../src/utils/pactl.c:374
-#: ../src/utils/pactl.c:418
-#: ../src/utils/pactl.c:419
-#: ../src/utils/pactl.c:425
-#: ../src/utils/pactl.c:468
-#: ../src/utils/pactl.c:469
-#: ../src/utils/pactl.c:473
+#: ../src/utils/pactl.c:246 ../src/utils/pactl.c:289 ../src/utils/pactl.c:322
+#: ../src/utils/pactl.c:366 ../src/utils/pactl.c:367 ../src/utils/pactl.c:374
+#: ../src/utils/pactl.c:418 ../src/utils/pactl.c:419 ../src/utils/pactl.c:425
+#: ../src/utils/pactl.c:468 ../src/utils/pactl.c:469 ../src/utils/pactl.c:473
 msgid "n/a"
 msgstr ""
 
@@ -1522,8 +1545,7 @@ msgstr "sink"
 msgid "source"
 msgstr "källa"
 
-#: ../src/utils/pactl.c:511
-#: ../src/utils/pactl.c:521
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
 #, c-format
 msgid "Failure: %s\n"
 msgstr "Fel: %s\n"
@@ -1557,8 +1579,10 @@ msgid ""
 "  -h, --help                            Show this help\n"
 "      --version                         Show version\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
 msgstr ""
 
 #: ../src/utils/pactl.c:729
@@ -1614,12 +1638,16 @@ msgstr ""
 
 #: ../src/utils/pactl.c:875
 #, c-format
-msgid "You may not specify more than one sink. You have to specify at least one boolean value.\n"
+msgid ""
+"You may not specify more than one sink. You have to specify at least one "
+"boolean value.\n"
 msgstr ""
 
 #: ../src/utils/pactl.c:888
 #, c-format
-msgid "You may not specify more than one source. You have to specify at least one boolean value.\n"
+msgid ""
+"You may not specify more than one source. You have to specify at least one "
+"boolean value.\n"
 msgstr ""
 
 #: ../src/utils/pactl.c:904
@@ -1634,7 +1662,8 @@ msgid ""
 "\n"
 " -d    Show current PulseAudio data attached to X11 display (default)\n"
 " -e    Export local PulseAudio data to X11 display\n"
-" -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
+" -i    Import PulseAudio data from X11 display to local environment "
+"variables and cookie file.\n"
 " -r    Remove PulseAudio data from X11 display\n"
 msgstr ""
 
@@ -1721,14 +1750,12 @@ msgstr ""
 msgid "select(): %s"
 msgstr "select(): %s"
 
-#: ../src/utils/pacmd.c:124
-#: ../src/utils/pacmd.c:140
+#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
 #, c-format
 msgid "read(): %s"
 msgstr "read(): %s"
 
-#: ../src/utils/pacmd.c:153
-#: ../src/utils/pacmd.c:167
+#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
 #, c-format
 msgid "write(): %s"
 msgstr "write(): %s"
@@ -1758,11 +1785,15 @@ msgid ""
 "\n"
 "  -v, --verbose                         Enable verbose operation\n"
 "\n"
-"  -s, --server=SERVER                   The name of the server to connect to\n"
+"  -s, --server=SERVER                   The name of the server to connect "
+"to\n"
 "  -d, --device=DEVICE                   The name of the sink to connect to\n"
-"  -n, --client-name=NAME                How to call this client on the server\n"
-"      --stream-name=NAME                How to call this stream on the server\n"
-"      --volume=VOLUME                   Specify the initial (linear) volume in range 0...65536\n"
+"  -n, --client-name=NAME                How to call this client on the "
+"server\n"
+"      --stream-name=NAME                How to call this stream on the "
+"server\n"
+"      --volume=VOLUME                   Specify the initial (linear) volume "
+"in range 0...65536\n"
 "      --channel-map=CHANNELMAP          Set the channel map to the use\n"
 msgstr ""
 
@@ -1797,3 +1828,9 @@ msgstr ""
 msgid "Using sample spec '%s'\n"
 msgstr ""
 
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
+msgid "Cannot access autospawn lock."
+msgstr ""
+
+#~ msgid "socketpair(): %s"
+#~ msgstr "socketpair(): %s"
index 543f4e8ec74fb0bc6881608bbf40e77025bed84e..72c38cc6a655d20bd77bf79e42196978d8aa3ab4 100644 (file)
@@ -1,3 +1,4 @@
+prioq-test
 lock-autospawn-test
 *.lo
 *.o
@@ -8,7 +9,7 @@ Makefile
 Makefile.in
 asyncmsgq-test
 asyncq-test
-bt-proximity-helper
+proximity-helper
 channelmap-test
 client.conf
 close-test
index 1663d66d965244a26a6a2176463e0f6a6c2895bc..f2771980bcbd6cb1def8e96c5980e09c742e77e0 100644 (file)
@@ -45,7 +45,7 @@ endif
 #     Compiler/linker flags       #
 ###################################
 
-AM_CFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src/modules -I$(top_builddir)/src/modules/rtp -I$(top_builddir)/src/modules/gconf
+AM_CFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src/modules -I$(top_builddir)/src/modules/rtp -I$(top_builddir)/src/modules/gconf -I$(top_builddir)/src/modules/bluetooth
 AM_CFLAGS += $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS
 AM_CFLAGS += $(LTDLINCL)
 AM_CFLAGS += $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) $(LIBSPEEX_CFLAGS)
@@ -62,8 +62,8 @@ AM_CFLAGS += -DPA_MACHINE_ID=\"$(localstatedir)/lib/dbus/machine-id\"
 # This cool debug trap works on i386/gcc only
 AM_CFLAGS += '-DDEBUG_TRAP=__asm__("int $$3")'
 
-AM_LIBADD = $(PTHREAD_LIBS)
-AM_LDADD = $(PTHREAD_LIBS)
+AM_LIBADD = $(PTHREAD_LIBS) $(INTLLIBS)
+AM_LDADD = $(PTHREAD_LIBS) $(INTLLIBS)
 
 # Only required on some platforms but defined for all to avoid errors
 AM_LDFLAGS = -Wl,-no-undefined -Wl,--gc-sections
@@ -263,7 +263,8 @@ noinst_PROGRAMS = \
                proplist-test \
                rtstutter \
                stripnul \
-               lock-autospawn-test
+               lock-autospawn-test \
+               prioq-test
 
 if HAVE_SIGXCPU
 noinst_PROGRAMS += \
@@ -458,6 +459,11 @@ lock_autospawn_test_LDADD = $(AM_LDADD) libpulsecore.la
 lock_autospawn_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
 lock_autospawn_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
 
+prioq_test_SOURCES = tests/prioq-test.c
+prioq_test_LDADD = $(AM_LDADD) libpulsecore.la
+prioq_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
+prioq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
+
 ###################################
 #         Client library          #
 ###################################
@@ -653,7 +659,7 @@ bin_SCRIPTS += utils/padsp
 
 endif
 
-libpulsedsp_la_SOURCES = utils/padsp.c pulsecore/core-util.c pulsecore/core-util.h pulsecore/core-error.c pulsecore/core-error.h  pulsecore/log.c pulsecore/log.h pulsecore/once.c pulsecore/once.h $(PA_THREAD_OBJS)
+libpulsedsp_la_SOURCES = utils/padsp.c pulsecore/core-util.c pulsecore/core-util.h pulsecore/core-error.c pulsecore/core-error.h  pulsecore/log.c pulsecore/log.h pulsecore/rtclock.c pulsecore/rtclock.h pulsecore/once.c pulsecore/once.h $(PA_THREAD_OBJS)
 libpulsedsp_la_CFLAGS = $(AM_CFLAGS)
 libpulsedsp_la_LIBADD = $(AM_LIBADD) libpulse.la
 libpulsedsp_la_LDFLAGS = -avoid-version
@@ -757,6 +763,7 @@ libpulsecore_la_SOURCES += \
                pulsecore/g711.c pulsecore/g711.h \
                pulsecore/hashmap.c pulsecore/hashmap.h \
                pulsecore/idxset.c pulsecore/idxset.h \
+               pulsecore/prioq.c pulsecore/prioq.h \
                pulsecore/log.c pulsecore/log.h \
                pulsecore/mcalign.c pulsecore/mcalign.h \
                pulsecore/memblock.c pulsecore/memblock.h \
@@ -1160,10 +1167,14 @@ endif
 
 if HAVE_BLUEZ
 modlibexec_LTLIBRARIES += \
-               module-bt-proximity.la
+               module-bluetooth-proximity.la \
+               module-bluetooth-discover.la \
+               libbluetooth-ipc.la \
+               libbluetooth-sbc.la \
+               module-bluetooth-device.la
 
 pulselibexec_PROGRAMS += \
-               bt-proximity-helper
+               proximity-helper
 endif
 
 # These are generated by a M4 script
@@ -1219,7 +1230,9 @@ SYMDEF_FILES = \
                modules/module-rescue-streams-symdef.h \
                modules/module-suspend-on-idle-symdef.h \
                modules/module-hal-detect-symdef.h \
-               modules/module-bt-proximity-symdef.h \
+               modules/bluetooth/module-bluetooth-proximity-symdef.h \
+               modules/bluetooth/module-bluetooth-discover-symdef.h \
+               modules/bluetooth/module-bluetooth-device-symdef.h \
                modules/gconf/module-gconf-symdef.h \
                modules/module-position-event-sounds-symdef.h \
                modules/module-console-kit-symdef.h
@@ -1231,6 +1244,7 @@ $(SYMDEF_FILES): modules/module-defs.h.m4
        $(MKDIR_P) modules
        $(MKDIR_P) modules/gconf
        $(MKDIR_P) modules/rtp
+       $(MKDIR_P) modules/bluetooth
        $(M4) -Dfname="$@" $< > $@
 
 # Simple protocol
@@ -1550,15 +1564,36 @@ gconf_helper_CFLAGS = $(AM_CFLAGS) $(GCONF_CFLAGS)
 gconf_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
 
 # Bluetooth proximity
-module_bt_proximity_la_SOURCES = modules/module-bt-proximity.c
-module_bt_proximity_la_LDFLAGS = -module -avoid-version
-module_bt_proximity_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore.la libdbus-util.la
-module_bt_proximity_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DPA_BT_PROXIMITY_HELPER=\"$(pulselibexecdir)/bt-proximity-helper\"
-
-bt_proximity_helper_SOURCES = modules/bt-proximity-helper.c
-bt_proximity_helper_LDADD = $(AM_LDADD) $(BLUEZ_LIBS)
-bt_proximity_helper_CFLAGS = $(AM_CFLAGS) $(BLUEZ_CFLAGS)
-bt_proximity_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+module_bluetooth_proximity_la_SOURCES = modules/bluetooth/module-bluetooth-proximity.c
+module_bluetooth_proximity_la_LDFLAGS = -module -avoid-version
+module_bluetooth_proximity_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore.la libdbus-util.la
+module_bluetooth_proximity_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS) -DPA_BT_PROXIMITY_HELPER=\"$(pulselibexecdir)/proximity-helper\"
+
+proximity_helper_SOURCES = modules/bluetooth/proximity-helper.c
+proximity_helper_LDADD = $(AM_LDADD) $(BLUEZ_LIBS)
+proximity_helper_CFLAGS = $(AM_CFLAGS) $(BLUEZ_CFLAGS)
+proximity_helper_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
+
+# Bluetooth sink / source
+module_bluetooth_discover_la_SOURCES = modules/bluetooth/module-bluetooth-discover.c
+module_bluetooth_discover_la_LDFLAGS = -module -avoid-version
+module_bluetooth_discover_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore.la libdbus-util.la
+module_bluetooth_discover_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+
+libbluetooth_sbc_la_SOURCES = modules/bluetooth/sbc.c modules/bluetooth/sbc.h modules/bluetooth/sbc_tables.h modules/bluetooth/sbc_math.h
+libbluetooth_sbc_la_LDFLAGS = -avoid-version
+libbluetooth_sbc_la_LIBADD = $(AM_LIBADD)
+libbluetooth_sbc_la_CFLAGS = $(AM_CFLAGS)
+
+libbluetooth_ipc_la_SOURCES = modules/bluetooth/ipc.c modules/bluetooth/ipc.h
+libbluetooth_ipc_la_LDFLAGS = -avoid-version
+libbluetooth_ipc_la_LIBADD = $(AM_LIBADD)
+libbluetooth_ipc_la_CFLAGS = $(AM_CFLAGS)
+
+module_bluetooth_device_la_SOURCES = modules/bluetooth/module-bluetooth-device.c modules/bluetooth/rtp.h
+module_bluetooth_device_la_LDFLAGS = -module -avoid-version
+module_bluetooth_device_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore.la libdbus-util.la libbluetooth-ipc.la libbluetooth-sbc.la libsocket-util.la
+module_bluetooth_device_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
 
 ###################################
 #        Some minor stuff         #
@@ -1607,7 +1642,7 @@ daemon.conf: daemon/daemon.conf.in Makefile
 install-exec-hook:
        chown root $(DESTDIR)$(bindir)/pulseaudio ; true
        chmod u+s $(DESTDIR)$(bindir)/pulseaudio
-       -chmod u+s $(DESTDIR)$(pulselibexecdir)/bt-proximity-helper
+       -chmod u+s $(DESTDIR)$(pulselibexecdir)/proximity-helper
        ln -sf pacat $(DESTDIR)$(bindir)/parec
        rm -f $(DESTDIR)$(modlibexecdir)/*.a
        rm -f $(DESTDIR)$(libdir)/libpulsedsp.a
index f7b6658bed37a0b923c4609cc5c0d90d57005089..707b5323579dec089eed5225d3031431398b6be6 100644 (file)
@@ -34,6 +34,7 @@
 #include <pulsecore/macro.h>
 #include <pulsecore/core-error.h>
 #include <pulsecore/log.h>
+#include <pulsecore/core-util.h>
 
 #ifdef HAVE_SYS_CAPABILITY_H
 #include <sys/capability.h>
@@ -112,9 +113,9 @@ void pa_drop_caps(void) {
 
 #ifndef __OPTIMIZE__
     /* Valgrind doesn't not know set_caps, so we bypass it here -- but
-     *  only in development builts.*/
+     * only in development builds.*/
 
-    if (getenv("VALGRIND") && !pa_have_caps())
+    if (pa_in_valgrind() && !pa_have_caps())
         return;
 #endif
 
index 77da3f7ebabea395019eb57403d4d8120bc18255..939b25d776c78a883c206da34ed1e89adf92338e 100644 (file)
@@ -84,7 +84,8 @@ static const pa_daemon_conf default_conf = {
     .disable_shm = FALSE,
     .default_n_fragments = 4,
     .default_fragment_size_msec = 25,
-    .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 }
+    .default_sample_spec = { .format = PA_SAMPLE_S16NE, .rate = 44100, .channels = 2 },
+    .shm_size = 0
 #ifdef HAVE_SYS_RESOURCE_H
    ,.rlimit_fsize = { .value = 0, .is_set = FALSE },
     .rlimit_data = { .value = 0, .is_set = FALSE },
@@ -429,6 +430,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
         { "disable-remixing",           pa_config_parse_bool,     NULL },
         { "disable-lfe-remixing",       pa_config_parse_bool,     NULL },
         { "load-default-script-file",   pa_config_parse_bool,     NULL },
+        { "shm-size-bytes",             pa_config_parse_size,     NULL },
 #ifdef HAVE_SYS_RESOURCE_H
         { "rlimit-fsize",               parse_rlimit,             NULL },
         { "rlimit-data",                parse_rlimit,             NULL },
@@ -494,65 +496,66 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
     table[26].data = &c->disable_remixing;
     table[27].data = &c->disable_lfe_remixing;
     table[28].data = &c->load_default_script_file;
+    table[29].data = &c->shm_size;
 #ifdef HAVE_SYS_RESOURCE_H
-    table[29].data = &c->rlimit_fsize;
-    table[30].data = &c->rlimit_data;
-    table[31].data = &c->rlimit_stack;
-    table[32].data = &c->rlimit_as;
-    table[33].data = &c->rlimit_core;
-    table[34].data = &c->rlimit_nofile;
-    table[35].data = &c->rlimit_as;
+    table[30].data = &c->rlimit_fsize;
+    table[31].data = &c->rlimit_data;
+    table[32].data = &c->rlimit_stack;
+    table[33].data = &c->rlimit_as;
+    table[34].data = &c->rlimit_core;
+    table[35].data = &c->rlimit_nofile;
+    table[36].data = &c->rlimit_as;
 #ifdef RLIMIT_NPROC
-    table[36].data = &c->rlimit_nproc;
+    table[37].data = &c->rlimit_nproc;
 #endif
 
 #ifdef RLIMIT_MEMLOCK
 #ifndef RLIMIT_NPROC
 #error "Houston, we have a numbering problem!"
 #endif
-    table[37].data = &c->rlimit_memlock;
+    table[38].data = &c->rlimit_memlock;
 #endif
 
 #ifdef RLIMIT_LOCKS
 #ifndef RLIMIT_MEMLOCK
 #error "Houston, we have a numbering problem!"
 #endif
-    table[38].data = &c->rlimit_locks;
+    table[39].data = &c->rlimit_locks;
 #endif
 
 #ifdef RLIMIT_SIGPENDING
 #ifndef RLIMIT_LOCKS
 #error "Houston, we have a numbering problem!"
 #endif
-    table[39].data = &c->rlimit_sigpending;
+    table[40].data = &c->rlimit_sigpending;
 #endif
 
 #ifdef RLIMIT_MSGQUEUE
 #ifndef RLIMIT_SIGPENDING
 #error "Houston, we have a numbering problem!"
 #endif
-    table[40].data = &c->rlimit_msgqueue;
+    table[41].data = &c->rlimit_msgqueue;
 #endif
 
 #ifdef RLIMIT_NICE
 #ifndef RLIMIT_MSGQUEUE
 #error "Houston, we have a numbering problem!"
 #endif
-    table[41].data = &c->rlimit_nice;
+    table[42].data = &c->rlimit_nice;
 #endif
 
 #ifdef RLIMIT_RTPRIO
 #ifndef RLIMIT_NICE
 #error "Houston, we have a numbering problem!"
 #endif
-    table[42].data = &c->rlimit_rtprio;
+    table[43].data = &c->rlimit_rtprio;
 #endif
 
 #ifdef RLIMIT_RTTIME
 #ifndef RLIMIT_RTTIME
 #error "Houston, we have a numbering problem!"
 #endif
-    table[43].data = &c->rlimit_rttime;
+    table[44].data = &c->rlimit_rttime;
 #endif
 #endif
 
@@ -670,6 +673,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
     pa_strbuf_printf(s, "default-sample-channels = %u\n", c->default_sample_spec.channels);
     pa_strbuf_printf(s, "default-fragments = %u\n", c->default_n_fragments);
     pa_strbuf_printf(s, "default-fragment-size-msec = %u\n", c->default_fragment_size_msec);
+    pa_strbuf_printf(s, "shm-size-bytes = %lu\n", (unsigned long) c->shm_size);
 #ifdef HAVE_SYS_RESOURCE_H
     pa_strbuf_printf(s, "rlimit-fsize = %li\n", c->rlimit_fsize.is_set ? (long int) c->rlimit_fsize.value : -1);
     pa_strbuf_printf(s, "rlimit-data = %li\n", c->rlimit_data.is_set ? (long int) c->rlimit_data.value : -1);
index 309a142850def4ade658ed2e7b67ae585224c29d..90329268e1cc1a1ae8844719a307cf608c6a30c7 100644 (file)
@@ -111,6 +111,7 @@ typedef struct pa_daemon_conf {
 
     unsigned default_n_fragments, default_fragment_size_msec;
     pa_sample_spec default_sample_spec;
+    size_t shm_size;
 } pa_daemon_conf;
 
 /* Allocate a new structure and fill it with sane defaults */
index ea09fe09c6fbd7dd1937ece47f4230fa7290a38d..c672d42049f9e03e0d5e833b235c8fe16f907335 100644 (file)
@@ -26,6 +26,7 @@
 ; use-pid-file = yes
 ; system-instance = no
 ; disable-shm = no
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
 
 ; high-priority = yes
 ; nice-level = -11
@@ -39,7 +40,7 @@
 
 ; dl-search-path = (depends on architecture)
 
-; load-defaul-script-file = yes
+; load-default-script-file = yes
 ; default-script-file = @PA_DEFAULT_CONFIG_FILE@
 
 ; log-target = auto
index 5f35e3ecc1dc177b4dbe452743ad190f23eb52f0..7032038deeb0e8260d94b179a0a55b4674906beb 100755 (executable)
@@ -48,6 +48,11 @@ load-module module-hal-detect
 load-module module-detect
 .endif
 
+### Automatically load driver modules for Bluetooth hardware
+#.ifexists module-bluetooth-discover@PA_SOEXT@
+#load-module module-bluetooth-discover
+#.endif
+
 ### Load several protocols
 .ifexists module-esound-protocol-unix@PA_SOEXT@
 load-module module-esound-protocol-unix
index a9e8ed4626afc94fa85e82c467a1a832106fd6bf..bc8bc63ebbfd407bf83b8a7be8ba33315bbcc42f 100644 (file)
@@ -646,9 +646,9 @@ int main(int argc, char *argv[]) {
         conf->disable_shm = TRUE;
     }
 
-    if (conf->system_instance && conf->exit_idle_time > 0) {
+    if (conf->system_instance && conf->exit_idle_time >= 0) {
         pa_log_notice(_("Running in system mode, forcibly disabling exit idle time!"));
-        conf->exit_idle_time = 0;
+        conf->exit_idle_time = -1;
     }
 
     if (conf->cmd == PA_CMD_START) {
@@ -793,6 +793,8 @@ int main(int argc, char *argv[]) {
     pa_log_debug(_("Compiled with Valgrind support: no"));
 #endif
 
+    pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
+
 #ifdef __OPTIMIZE__
     pa_log_debug(_("Optimized build: yes"));
 #else
@@ -854,7 +856,7 @@ int main(int argc, char *argv[]) {
 
     pa_assert_se(mainloop = pa_mainloop_new());
 
-    if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm))) {
+    if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) {
         pa_log(_("pa_core_new() failed."));
         goto finish;
     }
index f6052c4b96487f71b40ea21ba409945c64469766..27e428156abd8a52584ca25c8db21105cff72674 100755 (executable)
@@ -34,8 +34,9 @@ load-module module-esound-protocol-unix
 .endif
 load-module module-native-protocol-unix
 
-### Automatically restore the volume of playback streams
-load-module module-volume-restore
+### Automatically restore the volume of streams and devices
+load-module module-stream-restore
+load-module module-device-restore
 
 ### Automatically restore the default sink/source when changed by the user during runtime
 load-module module-default-device-restore
index 67a5ee36db16052fed514d43351b81f7a67c0277..7211914aab716647f3e28694050735f29550f3bc 100644 (file)
@@ -98,11 +98,14 @@ pa_context_unload_module;
 pa_context_unref;
 pa_cvolume_avg;
 pa_cvolume_channels_equal_to;
+pa_cvolume_compatible;
 pa_cvolume_equal;
+pa_cvolume_init;
 pa_cvolume_max;
 pa_cvolume_remap;
 pa_cvolume_set;
 pa_cvolume_snprint;
+pa_sw_cvolume_snprint_dB;
 pa_cvolume_valid;
 pa_ext_stream_restore_delete;
 pa_ext_stream_restore_read;
@@ -160,6 +163,7 @@ pa_proplist_update;
 pa_sample_format_to_string;
 pa_sample_size;
 pa_sample_spec_equal;
+pa_sample_spec_init;
 pa_sample_spec_snprint;
 pa_sample_spec_valid;
 pa_signal_done;
index c3eb72f5765d14121e048bb2293ec5c3cbea21ba..ffe7795edf0320d515e6f15e852ba9106a175d76 100644 (file)
@@ -1109,27 +1109,3 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
 
     return item;
 }
-
-pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t) {
-    unsigned i;
-
-    pa_assert(r);
-    pa_assert(t);
-    pa_assert(r->channels == t->channels);
-
-    for (i = 0; i < r->channels; i++) {
-        double a, b, c;
-
-        a = pa_sw_volume_to_linear(r->values[i]); /* the hw volume */
-        b = pa_sw_volume_to_linear(t->values[i]); /* the intended volume */
-
-        if (a <= 0)
-            c = 0;
-        else
-            c = b / a;
-
-        r->values[i] = pa_sw_volume_from_linear(c);
-    }
-
-    return r;
-}
index 7991a10764977112447484a960c98bc1fb31bec1..b66adc13583b8ec0f9afa08d8e374de4b61921ae 100644 (file)
@@ -92,6 +92,4 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents);
 
 pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll);
 
-pa_cvolume *pa_alsa_volume_divide(pa_cvolume *r, const pa_cvolume *t);
-
 #endif
diff --git a/src/modules/bluetooth/Makefile b/src/modules/bluetooth/Makefile
new file mode 120000 (symlink)
index 0000000..efe5a33
--- /dev/null
@@ -0,0 +1 @@
+../../pulse/Makefile
\ No newline at end of file
diff --git a/src/modules/bluetooth/ipc.c b/src/modules/bluetooth/ipc.c
new file mode 100644 (file)
index 0000000..9825699
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include "ipc.h"
+
+/* This table contains the string representation for messages */
+static const char *strmsg[] = {
+       "BT_GETCAPABILITIES_REQ",
+       "BT_GETCAPABILITIES_RSP",
+       "BT_SETCONFIGURATION_REQ",
+       "BT_SETCONFIGURATION_RSP",
+       "BT_STREAMSTART_REQ",
+       "BT_STREAMSTART_RSP",
+       "BT_STREAMSTOP_REQ",
+       "BT_STREAMSTOP_RSP",
+       "BT_STREAMSUSPEND_IND",
+       "BT_STREAMRESUME_IND",
+       "BT_CONTROL_REQ",
+       "BT_CONTROL_RSP",
+       "BT_CONTROL_IND",
+       "BT_STREAMFD_IND",
+};
+
+int bt_audio_service_open(void)
+{
+       int sk;
+       int err;
+       struct sockaddr_un addr = {
+               AF_UNIX, BT_IPC_SOCKET_NAME
+       };
+
+       sk = socket(PF_LOCAL, SOCK_STREAM, 0);
+       if (sk < 0) {
+               err = errno;
+               fprintf(stderr, "%s: Cannot open socket: %s (%d)\n",
+                       __FUNCTION__, strerror(err), err);
+               errno = err;
+               return -1;
+       }
+
+       if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+               err = errno;
+               fprintf(stderr, "%s: connect() failed: %s (%d)\n",
+                       __FUNCTION__, strerror(err), err);
+               close(sk);
+               errno = err;
+               return -1;
+       }
+
+       return sk;
+}
+
+int bt_audio_service_close(int sk)
+{
+       return close(sk);
+}
+
+int bt_audio_service_get_data_fd(int sk)
+{
+       char cmsg_b[CMSG_SPACE(sizeof(int))], m;
+       int err, ret;
+       struct iovec iov = { &m, sizeof(m) };
+       struct msghdr msgh;
+       struct cmsghdr *cmsg;
+
+       memset(&msgh, 0, sizeof(msgh));
+       msgh.msg_iov = &iov;
+       msgh.msg_iovlen = 1;
+       msgh.msg_control = &cmsg_b;
+       msgh.msg_controllen = CMSG_LEN(sizeof(int));
+
+       ret = (int) recvmsg(sk, &msgh, 0);
+       if (ret < 0) {
+               err = errno;
+               fprintf(stderr, "%s: Unable to receive fd: %s (%d)\n",
+                       __FUNCTION__, strerror(err), err);
+               errno = err;
+               return -1;
+       }
+
+       /* Receive auxiliary data in msgh */
+       for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL;
+                       cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
+               if (cmsg->cmsg_level == SOL_SOCKET
+                               && cmsg->cmsg_type == SCM_RIGHTS)
+                       return (*(int *) CMSG_DATA(cmsg));
+       }
+
+       errno = EINVAL;
+       return -1;
+}
+
+const char *bt_audio_strmsg(int type)
+{
+    if (type < 0 || (size_t) type > (sizeof(strmsg) / sizeof(strmsg[0])))
+               return NULL;
+
+       return strmsg[type];
+}
diff --git a/src/modules/bluetooth/ipc.h b/src/modules/bluetooth/ipc.h
new file mode 100644 (file)
index 0000000..ae85e72
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+/*
+  Message sequence chart of streaming sequence for A2DP transport
+
+  Audio daemon                       User
+                             on snd_pcm_open
+                 <--BT_GETCAPABILITIES_REQ
+
+  BT_GETCAPABILITIES_RSP-->
+
+                        on snd_pcm_hw_params
+                <--BT_SETCONFIGURATION_REQ
+
+  BT_SETCONFIGURATION_RSP-->
+
+                       on snd_pcm_prepare
+                <--BT_STREAMSTART_REQ
+
+  <Moves to streaming state>
+  BT_STREAMSTART_RSP-->
+
+  BT_STREAMFD_IND -->
+
+                          <  streams data >
+                             ..........
+
+               on snd_pcm_drop/snd_pcm_drain
+
+                <--BT_STREAMSTOP_REQ
+
+  <Moves to open state>
+  BT_STREAMSTOP_RSP-->
+
+                       on IPC close or appl crash
+  <Moves to idle>
+
+ */
+
+#ifndef BT_AUDIOCLIENT_H
+#define BT_AUDIOCLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+
+#define BT_AUDIO_IPC_PACKET_SIZE   128
+#define BT_IPC_SOCKET_NAME "\0/org/bluez/audio"
+
+/* Generic message header definition, except for RSP messages */
+typedef struct {
+       uint8_t msg_type;
+} __attribute__ ((packed)) bt_audio_msg_header_t;
+
+/* Generic message header definition, for all RSP messages */
+typedef struct {
+       bt_audio_msg_header_t   msg_h;
+       uint8_t                 posix_errno;
+} __attribute__ ((packed)) bt_audio_rsp_msg_header_t;
+
+/* Messages list */
+#define BT_GETCAPABILITIES_REQ         0
+#define BT_GETCAPABILITIES_RSP         1
+
+#define BT_SETCONFIGURATION_REQ                2
+#define BT_SETCONFIGURATION_RSP                3
+
+#define BT_STREAMSTART_REQ             4
+#define BT_STREAMSTART_RSP             5
+
+#define BT_STREAMSTOP_REQ              6
+#define BT_STREAMSTOP_RSP              7
+
+#define BT_STREAMSUSPEND_IND           8
+#define BT_STREAMRESUME_IND            9
+
+#define BT_CONTROL_REQ                10
+#define BT_CONTROL_RSP                11
+#define BT_CONTROL_IND                12
+
+#define BT_STREAMFD_IND                       13
+
+/* BT_GETCAPABILITIES_REQ */
+
+#define BT_CAPABILITIES_TRANSPORT_A2DP 0
+#define BT_CAPABILITIES_TRANSPORT_SCO  1
+#define BT_CAPABILITIES_TRANSPORT_ANY  2
+
+#define BT_CAPABILITIES_ACCESS_MODE_READ       1
+#define BT_CAPABILITIES_ACCESS_MODE_WRITE      2
+#define BT_CAPABILITIES_ACCESS_MODE_READWRITE  3
+
+#define BT_FLAG_AUTOCONNECT    1
+
+struct bt_getcapabilities_req {
+       bt_audio_msg_header_t   h;
+       char                    device[18];     /* Address of the remote Device */
+       uint8_t                 transport;      /* Requested transport */
+       uint8_t                 flags;          /* Requested flags */
+} __attribute__ ((packed));
+
+/* BT_GETCAPABILITIES_RSP */
+
+/**
+ * SBC Codec parameters as per A2DP profile 1.0 § 4.3
+ */
+
+#define BT_SBC_SAMPLING_FREQ_16000             (1 << 3)
+#define BT_SBC_SAMPLING_FREQ_32000             (1 << 2)
+#define BT_SBC_SAMPLING_FREQ_44100             (1 << 1)
+#define BT_SBC_SAMPLING_FREQ_48000             1
+
+#define BT_A2DP_CHANNEL_MODE_MONO              (1 << 3)
+#define BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL      (1 << 2)
+#define BT_A2DP_CHANNEL_MODE_STEREO            (1 << 1)
+#define BT_A2DP_CHANNEL_MODE_JOINT_STEREO      1
+
+#define BT_A2DP_BLOCK_LENGTH_4                 (1 << 3)
+#define BT_A2DP_BLOCK_LENGTH_8                 (1 << 2)
+#define BT_A2DP_BLOCK_LENGTH_12                        (1 << 1)
+#define BT_A2DP_BLOCK_LENGTH_16                        1
+
+#define BT_A2DP_SUBBANDS_4                     (1 << 1)
+#define BT_A2DP_SUBBANDS_8                     1
+
+#define BT_A2DP_ALLOCATION_SNR                 (1 << 1)
+#define BT_A2DP_ALLOCATION_LOUDNESS            1
+
+#define BT_MPEG_SAMPLING_FREQ_16000            (1 << 5)
+#define BT_MPEG_SAMPLING_FREQ_22050            (1 << 4)
+#define BT_MPEG_SAMPLING_FREQ_24000            (1 << 3)
+#define BT_MPEG_SAMPLING_FREQ_32000            (1 << 2)
+#define BT_MPEG_SAMPLING_FREQ_44100            (1 << 1)
+#define BT_MPEG_SAMPLING_FREQ_48000            1
+
+#define BT_MPEG_LAYER_1                                (1 << 2)
+#define BT_MPEG_LAYER_2                                (1 << 1)
+#define BT_MPEG_LAYER_3                                1
+
+typedef struct {
+       uint8_t channel_mode;
+       uint8_t frequency;
+       uint8_t allocation_method;
+       uint8_t subbands;
+       uint8_t block_length;
+       uint8_t min_bitpool;
+       uint8_t max_bitpool;
+} __attribute__ ((packed)) sbc_capabilities_t;
+
+typedef struct {
+       uint8_t channel_mode;
+       uint8_t crc;
+       uint8_t layer;
+       uint8_t frequency;
+       uint8_t mpf;
+       uint16_t bitrate;
+} __attribute__ ((packed)) mpeg_capabilities_t;
+
+struct bt_getcapabilities_rsp {
+       bt_audio_rsp_msg_header_t       rsp_h;
+       uint8_t                         transport;         /* Granted transport */
+       sbc_capabilities_t              sbc_capabilities;  /* A2DP only */
+       mpeg_capabilities_t             mpeg_capabilities; /* A2DP only */
+       uint16_t                        sampling_rate;     /* SCO only */
+} __attribute__ ((packed));
+
+/* BT_SETCONFIGURATION_REQ */
+struct bt_setconfiguration_req {
+       bt_audio_msg_header_t   h;
+       char                    device[18];             /* Address of the remote Device */
+       uint8_t                 transport;              /* Requested transport */
+       uint8_t                 access_mode;            /* Requested access mode */
+       sbc_capabilities_t      sbc_capabilities;       /* A2DP only - only one of this field
+                                                       and next one must be filled */
+       mpeg_capabilities_t     mpeg_capabilities;      /* A2DP only */
+} __attribute__ ((packed));
+
+/* BT_SETCONFIGURATION_RSP */
+struct bt_setconfiguration_rsp {
+       bt_audio_rsp_msg_header_t       rsp_h;
+       uint8_t                         transport;      /* Granted transport */
+       uint8_t                         access_mode;    /* Granted access mode */
+       uint16_t                        link_mtu;       /* Max length that transport supports */
+} __attribute__ ((packed));
+
+/* BT_STREAMSTART_REQ */
+#define BT_STREAM_ACCESS_READ          0
+#define BT_STREAM_ACCESS_WRITE         1
+#define BT_STREAM_ACCESS_READWRITE     2
+struct bt_streamstart_req {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
+/* BT_STREAMSTART_RSP */
+struct bt_streamstart_rsp {
+       bt_audio_rsp_msg_header_t       rsp_h;
+} __attribute__ ((packed));
+
+/* BT_STREAMFD_IND */
+/* This message is followed by one byte of data containing the stream data fd
+   as ancilliary data */
+struct bt_streamfd_ind {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
+/* BT_STREAMSTOP_REQ */
+struct bt_streamstop_req {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
+/* BT_STREAMSTOP_RSP */
+struct bt_streamstop_rsp {
+       bt_audio_rsp_msg_header_t       rsp_h;
+} __attribute__ ((packed));
+
+/* BT_STREAMSUSPEND_IND */
+struct bt_streamsuspend_ind {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
+/* BT_STREAMRESUME_IND */
+struct bt_streamresume_ind {
+       bt_audio_msg_header_t   h;
+} __attribute__ ((packed));
+
+/* BT_CONTROL_REQ */
+
+#define BT_CONTROL_KEY_POWER                   0x40
+#define BT_CONTROL_KEY_VOL_UP                  0x41
+#define BT_CONTROL_KEY_VOL_DOWN                        0x42
+#define BT_CONTROL_KEY_MUTE                    0x43
+#define BT_CONTROL_KEY_PLAY                    0x44
+#define BT_CONTROL_KEY_STOP                    0x45
+#define BT_CONTROL_KEY_PAUSE                   0x46
+#define BT_CONTROL_KEY_RECORD                  0x47
+#define BT_CONTROL_KEY_REWIND                  0x48
+#define BT_CONTROL_KEY_FAST_FORWARD            0x49
+#define BT_CONTROL_KEY_EJECT                   0x4A
+#define BT_CONTROL_KEY_FORWARD                 0x4B
+#define BT_CONTROL_KEY_BACKWARD                        0x4C
+
+struct bt_control_req {
+       bt_audio_msg_header_t   h;
+       uint8_t                 mode;           /* Control Mode */
+       uint8_t                 key;            /* Control Key */
+} __attribute__ ((packed));
+
+/* BT_CONTROL_RSP */
+struct bt_control_rsp {
+       bt_audio_rsp_msg_header_t       rsp_h;
+       uint8_t                         mode;   /* Control Mode */
+       uint8_t                         key;    /* Control Key */
+} __attribute__ ((packed));
+
+/* BT_CONTROL_IND */
+struct bt_control_ind {
+       bt_audio_msg_header_t   h;
+       uint8_t                 mode;           /* Control Mode */
+       uint8_t                 key;            /* Control Key */
+} __attribute__ ((packed));
+
+/* Function declaration */
+
+/* Opens a connection to the audio service: return a socket descriptor */
+int bt_audio_service_open(void);
+
+/* Closes a connection to the audio service */
+int bt_audio_service_close(int sk);
+
+/* Receives stream data file descriptor : must be called after a
+BT_STREAMFD_IND message is returned */
+int bt_audio_service_get_data_fd(int sk);
+
+/* Human readable message type string */
+const char *bt_audio_strmsg(int type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BT_AUDIOCLIENT_H */
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
new file mode 100644 (file)
index 0000000..3460fe9
--- /dev/null
@@ -0,0 +1,922 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2008 Joao Paulo Rechi Vita
+
+    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 <string.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/ioctl.h>
+#include <linux/sockios.h>
+#include <arpa/inet.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
+#include <pulse/sample.h>
+#include <pulsecore/module.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/core-error.h>
+#include <pulsecore/socket-util.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/rtpoll.h>
+#include <pulsecore/time-smoother.h>
+#include <pulsecore/rtclock.h>
+
+#include "../dbus-util.h"
+#include "module-bluetooth-device-symdef.h"
+#include "ipc.h"
+#include "sbc.h"
+#include "rtp.h"
+
+#define DEFAULT_SINK_NAME "bluetooth_sink"
+#define BUFFER_SIZE 2048
+#define MAX_BITPOOL 64
+#define MIN_BITPOOL 2U
+#define SOL_SCO 17
+#define SCO_TXBUFS 0x03
+#define SCO_RXBUFS 0x04
+
+PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("Bluetooth audio sink and source");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+        "sink_name=<name of the device> "
+        "address=<address of the device> "
+        "profile=<a2dp|hsp>");
+
+struct bt_a2dp {
+    sbc_capabilities_t sbc_capabilities;
+    sbc_t sbc;                           /* Codec data */
+    pa_bool_t sbc_initialized;           /* Keep track if the encoder is initialized */
+    size_t codesize;                     /* SBC codesize */
+    unsigned samples;                    /* Number of encoded samples */
+    uint8_t buffer[BUFFER_SIZE];         /* Codec transfer buffer */
+    size_t count;                        /* Codec transfer buffer counter */
+
+    unsigned total_samples;              /* Cumulative number of codec samples */
+    uint16_t seq_num;                    /* Cumulative packet sequence */
+    unsigned frame_count;                /* Current frames in buffer*/
+};
+
+struct userdata {
+    pa_core *core;
+    pa_module *module;
+    pa_sink *sink;
+
+    pa_thread_mq thread_mq;
+    pa_rtpoll *rtpoll;
+    pa_rtpoll_item *rtpoll_item;
+    pa_thread *thread;
+
+    uint64_t offset;
+    pa_smoother *smoother;
+
+    char *name;
+    char *addr;
+    char *profile;
+    pa_sample_spec ss;
+
+    int audioservice_fd;
+    int stream_fd;
+
+    uint8_t transport;
+    char *strtransport;
+    size_t link_mtu;
+    size_t block_size;
+    pa_usec_t latency;
+
+    struct bt_a2dp a2dp;
+};
+
+static const char* const valid_modargs[] = {
+    "sink_name",
+    "address",
+    "profile",
+    "rate",
+    "channels",
+    NULL
+};
+
+static int bt_audioservice_send(int sk, const bt_audio_msg_header_t *msg) {
+    int e;
+    pa_log_debug("sending %s", bt_audio_strmsg(msg->msg_type));
+    if (send(sk, msg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0)
+        e = 0;
+    else {
+        e = -errno;
+        pa_log_error("Error sending data to audio service: %s(%d)", pa_cstrerror(errno), errno);
+    }
+    return e;
+}
+
+static int bt_audioservice_recv(int sk, bt_audio_msg_header_t *inmsg) {
+    int e;
+    const char *type;
+
+    pa_log_debug("trying to receive msg from audio service...");
+    if (recv(sk, inmsg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0) {
+        type = bt_audio_strmsg(inmsg->msg_type);
+        if (type) {
+            pa_log_debug("Received %s", type);
+            e = 0;
+        }
+        else {
+            e = -EINVAL;
+            pa_log_error("Bogus message type %d received from audio service", inmsg->msg_type);
+        }
+    }
+    else {
+        e = -errno;
+        pa_log_error("Error receiving data from audio service: %s(%d)", pa_cstrerror(errno), errno);
+    }
+
+    return e;
+}
+
+static int bt_audioservice_expect(int sk, bt_audio_msg_header_t *rsp_hdr, int expected_type) {
+    int e = bt_audioservice_recv(sk, rsp_hdr);
+    if (e == 0) {
+        if (rsp_hdr->msg_type != expected_type) {
+            e = -EINVAL;
+            pa_log_error("Bogus message %s received while %s was expected", bt_audio_strmsg(rsp_hdr->msg_type),
+                    bt_audio_strmsg(expected_type));
+        }
+    }
+    return e;
+}
+
+static int bt_getcaps(struct userdata *u) {
+    int e;
+    union {
+        bt_audio_rsp_msg_header_t rsp_hdr;
+        struct bt_getcapabilities_req getcaps_req;
+        struct bt_getcapabilities_rsp getcaps_rsp;
+        uint8_t buf[BT_AUDIO_IPC_PACKET_SIZE];
+    } msg;
+
+    memset(msg.buf, 0, BT_AUDIO_IPC_PACKET_SIZE);
+    msg.getcaps_req.h.msg_type = BT_GETCAPABILITIES_REQ;
+    strncpy(msg.getcaps_req.device, u->addr, 18);
+    if (strcasecmp(u->profile, "a2dp") == 0)
+        msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
+    else if (strcasecmp(u->profile, "hsp") == 0)
+        msg.getcaps_req.transport = BT_CAPABILITIES_TRANSPORT_SCO;
+    else {
+        pa_log_error("Invalid profile argument: %s", u->profile);
+        return -1;
+    }
+    msg.getcaps_req.flags = BT_FLAG_AUTOCONNECT;
+
+    e = bt_audioservice_send(u->audioservice_fd, &msg.getcaps_req.h);
+    if (e < 0) {
+        pa_log_error("Failed to send GETCAPABILITIES_REQ");
+        return e;
+    }
+
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp_hdr.msg_h, BT_GETCAPABILITIES_RSP);
+    if (e < 0) {
+        pa_log_error("Failed to expect for GETCAPABILITIES_RSP");
+        return e;
+    }
+    if (msg.rsp_hdr.posix_errno != 0) {
+        pa_log_error("BT_GETCAPABILITIES failed : %s (%d)", pa_cstrerror(msg.rsp_hdr.posix_errno), msg.rsp_hdr.posix_errno);
+        return -msg.rsp_hdr.posix_errno;
+    }
+
+    if ((u->transport = msg.getcaps_rsp.transport) == BT_CAPABILITIES_TRANSPORT_A2DP)
+        u->a2dp.sbc_capabilities = msg.getcaps_rsp.sbc_capabilities;
+
+    return 0;
+}
+
+static uint8_t default_bitpool(uint8_t freq, uint8_t mode) {
+    switch (freq) {
+        case BT_SBC_SAMPLING_FREQ_16000:
+        case BT_SBC_SAMPLING_FREQ_32000:
+            return 53;
+        case BT_SBC_SAMPLING_FREQ_44100:
+            switch (mode) {
+                case BT_A2DP_CHANNEL_MODE_MONO:
+                case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
+                    return 31;
+                case BT_A2DP_CHANNEL_MODE_STEREO:
+                case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
+                    return 53;
+                default:
+                    pa_log_warn("Invalid channel mode %u", mode);
+                    return 53;
+            }
+        case BT_SBC_SAMPLING_FREQ_48000:
+            switch (mode) {
+                case BT_A2DP_CHANNEL_MODE_MONO:
+                case BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL:
+                    return 29;
+                case BT_A2DP_CHANNEL_MODE_STEREO:
+                case BT_A2DP_CHANNEL_MODE_JOINT_STEREO:
+                    return 51;
+                default:
+                    pa_log_warn("Invalid channel mode %u", mode);
+                    return 51;
+            }
+        default:
+            pa_log_warn("Invalid sampling freq %u", freq);
+            return 53;
+    }
+}
+
+static int bt_a2dp_init(struct userdata *u) {
+    sbc_capabilities_t *cap = &u->a2dp.sbc_capabilities;
+    uint8_t max_bitpool, min_bitpool;
+    unsigned i;
+
+    static const struct {
+        uint32_t rate;
+        uint8_t cap;
+    } freq_table[] = {
+        { 16000U, BT_SBC_SAMPLING_FREQ_16000 },
+        { 32000U, BT_SBC_SAMPLING_FREQ_32000 },
+        { 44100U, BT_SBC_SAMPLING_FREQ_44100 },
+        { 48000U, BT_SBC_SAMPLING_FREQ_48000 }
+    };
+
+    /* Find the lowest freq that is at least as high as the requested
+     * sampling rate */
+    for (i = 0; i < PA_ELEMENTSOF(freq_table); i++)
+        if (freq_table[i].rate >= u->ss.rate || i == PA_ELEMENTSOF(freq_table)-1 ) {
+            u->ss.rate = freq_table[i].rate;
+            cap->frequency = freq_table[i].cap;
+            break;
+        }
+
+    if (u->ss.channels >= 2) {
+        if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
+            cap->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
+        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
+            cap->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
+        else if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL)
+            cap->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
+
+        u->ss.channels = 2;
+    } else {
+        if (cap->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
+            cap->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
+    }
+
+    if (!cap->channel_mode) {
+        pa_log_error("No supported channel modes");
+        return -1;
+    }
+
+    if (cap->block_length & BT_A2DP_BLOCK_LENGTH_16)
+        cap->block_length = BT_A2DP_BLOCK_LENGTH_16;
+    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_12)
+        cap->block_length = BT_A2DP_BLOCK_LENGTH_12;
+    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_8)
+        cap->block_length = BT_A2DP_BLOCK_LENGTH_8;
+    else if (cap->block_length & BT_A2DP_BLOCK_LENGTH_4)
+        cap->block_length = BT_A2DP_BLOCK_LENGTH_4;
+    else {
+        pa_log_error("No supported block lengths");
+        return -1;
+    }
+
+    if (cap->subbands & BT_A2DP_SUBBANDS_8)
+        cap->subbands = BT_A2DP_SUBBANDS_8;
+    else if (cap->subbands & BT_A2DP_SUBBANDS_4)
+        cap->subbands = BT_A2DP_SUBBANDS_4;
+    else {
+        pa_log_error("No supported subbands");
+        return -1;
+    }
+
+    if (cap->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS)
+        cap->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
+    else if (cap->allocation_method & BT_A2DP_ALLOCATION_SNR)
+        cap->allocation_method = BT_A2DP_ALLOCATION_SNR;
+
+    min_bitpool = (uint8_t) PA_MAX(MIN_BITPOOL, cap->min_bitpool);
+    max_bitpool = (uint8_t) PA_MIN(default_bitpool(cap->frequency, cap->channel_mode), cap->max_bitpool);
+
+    cap->min_bitpool = (uint8_t) min_bitpool;
+    cap->max_bitpool = (uint8_t) max_bitpool;
+
+    return 0;
+}
+
+static void bt_a2dp_setup(struct bt_a2dp *a2dp) {
+    sbc_capabilities_t active_capabilities = a2dp->sbc_capabilities;
+
+    if (a2dp->sbc_initialized)
+        sbc_reinit(&a2dp->sbc, 0);
+    else
+        sbc_init(&a2dp->sbc, 0);
+    a2dp->sbc_initialized = TRUE;
+
+    if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_16000)
+        a2dp->sbc.frequency = SBC_FREQ_16000;
+
+    if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_32000)
+        a2dp->sbc.frequency = SBC_FREQ_32000;
+
+    if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_44100)
+        a2dp->sbc.frequency = SBC_FREQ_44100;
+
+    if (active_capabilities.frequency & BT_SBC_SAMPLING_FREQ_48000)
+        a2dp->sbc.frequency = SBC_FREQ_48000;
+
+    if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
+        a2dp->sbc.mode = SBC_MODE_MONO;
+
+    if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL)
+        a2dp->sbc.mode = SBC_MODE_DUAL_CHANNEL;
+
+    if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_STEREO)
+        a2dp->sbc.mode = SBC_MODE_STEREO;
+
+    if (active_capabilities.channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO)
+        a2dp->sbc.mode = SBC_MODE_JOINT_STEREO;
+
+    a2dp->sbc.allocation = (uint8_t) (active_capabilities.allocation_method == BT_A2DP_ALLOCATION_SNR ? SBC_AM_SNR : SBC_AM_LOUDNESS);
+
+    switch (active_capabilities.subbands) {
+        case BT_A2DP_SUBBANDS_4:
+            a2dp->sbc.subbands = SBC_SB_4;
+            break;
+        case BT_A2DP_SUBBANDS_8:
+            a2dp->sbc.subbands = SBC_SB_8;
+            break;
+    }
+
+    switch (active_capabilities.block_length) {
+        case BT_A2DP_BLOCK_LENGTH_4:
+            a2dp->sbc.blocks = SBC_BLK_4;
+            break;
+        case BT_A2DP_BLOCK_LENGTH_8:
+            a2dp->sbc.blocks = SBC_BLK_8;
+            break;
+        case BT_A2DP_BLOCK_LENGTH_12:
+            a2dp->sbc.blocks = SBC_BLK_12;
+            break;
+        case BT_A2DP_BLOCK_LENGTH_16:
+            a2dp->sbc.blocks = SBC_BLK_16;
+            break;
+    }
+
+    a2dp->sbc.bitpool = active_capabilities.max_bitpool;
+    a2dp->codesize = (uint16_t) sbc_get_codesize(&a2dp->sbc);
+    a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
+}
+
+static int bt_setconf(struct userdata *u) {
+    int e;
+    union {
+        bt_audio_rsp_msg_header_t rsp_hdr;
+        struct bt_setconfiguration_req setconf_req;
+        struct bt_setconfiguration_rsp setconf_rsp;
+        uint8_t buf[BT_AUDIO_IPC_PACKET_SIZE];
+    } msg;
+
+    if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
+        e = bt_a2dp_init(u);
+        if (e < 0) {
+            pa_log_error("a2dp_init error");
+            return e;
+        }
+        u->ss.format = PA_SAMPLE_S16LE;
+    }
+    else
+        u->ss.format = PA_SAMPLE_U8;
+
+    memset(msg.buf, 0, BT_AUDIO_IPC_PACKET_SIZE);
+    msg.setconf_req.h.msg_type = BT_SETCONFIGURATION_REQ;
+    strncpy(msg.setconf_req.device, u->addr, 18);
+    msg.setconf_req.transport = u->transport;
+    if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP)
+        msg.setconf_req.sbc_capabilities = u->a2dp.sbc_capabilities;
+    msg.setconf_req.access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;
+
+    e = bt_audioservice_send(u->audioservice_fd, &msg.setconf_req.h);
+    if (e < 0) {
+        pa_log_error("Failed to send BT_SETCONFIGURATION_REQ");
+        return e;
+    }
+
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp_hdr.msg_h, BT_SETCONFIGURATION_RSP);
+    if (e < 0) {
+        pa_log_error("Failed to expect BT_SETCONFIGURATION_RSP");
+        return e;
+    }
+
+    if (msg.rsp_hdr.posix_errno != 0) {
+        pa_log_error("BT_SETCONFIGURATION failed : %s(%d)", pa_cstrerror(msg.rsp_hdr.posix_errno), msg.rsp_hdr.posix_errno);
+        return -msg.rsp_hdr.posix_errno;
+    }
+
+    u->transport = msg.setconf_rsp.transport;
+    u->strtransport = (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP ? pa_xstrdup("A2DP") : pa_xstrdup("SCO"));
+    u->link_mtu = msg.setconf_rsp.link_mtu;
+
+    /* setup SBC encoder now we agree on parameters */
+    if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
+        bt_a2dp_setup(&u->a2dp);
+        u->block_size = u->a2dp.codesize;
+        pa_log_info("sbc parameters:\n\tallocation=%u\n\tsubbands=%u\n\tblocks=%u\n\tbitpool=%u\n",
+                u->a2dp.sbc.allocation, u->a2dp.sbc.subbands, u->a2dp.sbc.blocks, u->a2dp.sbc.bitpool);
+    }
+    else
+        u->block_size = u->link_mtu;
+
+    return 0;
+}
+
+static int bt_getstreamfd(struct userdata *u) {
+    int e;
+//    uint32_t period_count = io->buffer_size / io->period_size;
+    union {
+        bt_audio_rsp_msg_header_t rsp_hdr;
+        struct bt_streamstart_req start_req;
+        struct bt_streamfd_ind streamfd_ind;
+        uint8_t buf[BT_AUDIO_IPC_PACKET_SIZE];
+    } msg;
+
+    memset(msg.buf, 0, BT_AUDIO_IPC_PACKET_SIZE);
+    msg.start_req.h.msg_type = BT_STREAMSTART_REQ;
+
+    e = bt_audioservice_send(u->audioservice_fd, &msg.start_req.h);
+    if (e < 0) {
+        pa_log_error("Failed to send BT_STREAMSTART_REQ");
+        return e;
+    }
+
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.rsp_hdr.msg_h, BT_STREAMSTART_RSP);
+    if (e < 0) {
+        pa_log_error("Failed to expect BT_STREAMSTART_RSP");
+        return e;
+    }
+
+    if (msg.rsp_hdr.posix_errno != 0) {
+        pa_log_error("BT_START failed : %s(%d)", pa_cstrerror(msg.rsp_hdr.posix_errno), msg.rsp_hdr.posix_errno);
+        return -msg.rsp_hdr.posix_errno;
+    }
+
+    e = bt_audioservice_expect(u->audioservice_fd, &msg.streamfd_ind.h, BT_STREAMFD_IND);
+    if (e < 0) {
+        pa_log_error("Failed to expect BT_STREAMFD_IND");
+        return e;
+    }
+
+    if (u->stream_fd >= 0)
+        pa_close(u->stream_fd);
+
+    u->stream_fd = bt_audio_service_get_data_fd(u->audioservice_fd);
+    if (u->stream_fd < 0) {
+        pa_log_error("Failed to get data fd: %s (%d)",pa_cstrerror(errno), errno);
+        return -errno;
+    }
+
+//   if (setsockopt(u->stream_fd, SOL_SCO, SCO_TXBUFS, &period_count, sizeof(period_count)) == 0)
+//       return 0;
+//   if (setsockopt(u->stream_fd, SOL_SCO, SO_SNDBUF, &period_count, sizeof(period_count)) == 0)
+//       return 0;
+//   /* FIXME : handle error codes */
+    pa_make_fd_nonblock(u->stream_fd);
+//    pa_make_socket_low_delay(u->stream_fd);
+
+    return 0;
+}
+
+static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
+    struct userdata *u = PA_SINK(o)->userdata;
+
+    pa_log_debug("got message: %d", code);
+    switch (code) {
+
+        case PA_SINK_MESSAGE_SET_STATE:
+            switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
+                case PA_SINK_SUSPENDED:
+                    pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
+                    pa_smoother_pause(u->smoother, pa_rtclock_usec());
+                    break;
+                case PA_SINK_IDLE:
+                case PA_SINK_RUNNING:
+                    if (u->sink->thread_info.state == PA_SINK_SUSPENDED)
+                        pa_smoother_resume(u->smoother, pa_rtclock_usec());
+                    break;
+                case PA_SINK_UNLINKED:
+                case PA_SINK_INIT:
+                    ;
+            }
+            break;
+
+        case PA_SINK_MESSAGE_GET_LATENCY: {
+            pa_usec_t w, r;
+/*             r = pa_smoother_get(u->smoother, pa_rtclock_usec()); */
+/* /\*             w = pa_bytes_to_usec(u->offset + (uint64_t) u->memchunk.length, &u->sink->sample_spec); *\/ */
+            *((pa_usec_t*) data) = /*w > r ? w - r :*/ 0;
+            return 0;
+        }
+
+    }
+
+    return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+static int sco_process_render(struct userdata *u) {
+    void *p;
+    int ret = 0;
+    pa_memchunk memchunk;
+
+    pa_sink_render_full(u->sink, u->block_size, &memchunk);
+
+    p = pa_memblock_acquire(memchunk.memblock);
+
+    for (;;) {
+        ssize_t l;
+
+        l = pa_loop_write(u->stream_fd, (uint8_t*) p, memchunk.length, NULL);
+        pa_log_debug("Memblock written to socket: %li bytes", (long) l);
+
+        pa_assert(l != 0);
+
+        if (l > 0) {
+            u->offset += (uint64_t) l;
+            break;
+        }
+
+        if (errno == EINTR)
+            pa_log_debug("EINTR");
+        else if (errno == EAGAIN)
+            pa_log_debug("EAGAIN");
+        else {
+            pa_log_error("Failed to write data to FIFO: %s", pa_cstrerror(errno));
+            ret = -1;
+            break;
+        }
+    }
+
+    pa_memblock_release(memchunk.memblock);
+    pa_memblock_unref(memchunk.memblock);
+
+    return ret;
+}
+
+static int a2dp_process_render(struct userdata *u) {
+    int written;
+
+    struct bt_a2dp *a2dp = &u->a2dp;
+    struct rtp_header *header = (void *) a2dp->buffer;
+    struct rtp_payload *payload = (void *) (a2dp->buffer + sizeof(*header));
+
+    pa_assert(u);
+
+    do {
+        /* Render some data */
+        int frame_size, encoded;
+        void *p;
+        pa_memchunk memchunk;
+
+        pa_sink_render_full(u->sink, u->block_size, &memchunk);
+
+        p = pa_memblock_acquire(memchunk.memblock);
+
+        frame_size = (uint16_t) sbc_get_frame_length(&a2dp->sbc);
+        pa_log_debug("SBC frame_size: %d", frame_size);
+
+        encoded = sbc_encode(&a2dp->sbc, p, (int) a2dp->codesize, a2dp->buffer + a2dp->count,
+                             (int) (sizeof(a2dp->buffer) - a2dp->count), &written);
+        pa_log_debug("SBC: encoded: %d; written: %d", encoded, written);
+
+        pa_memblock_release(memchunk.memblock);
+        pa_memblock_unref(memchunk.memblock);
+
+        if (encoded <= 0) {
+            pa_log_error("SBC encoding error (%d)", encoded);
+            return -1;
+        }
+
+        a2dp->count += (size_t) written;
+        a2dp->frame_count++;
+        a2dp->samples += (unsigned) encoded / frame_size;
+        a2dp->total_samples += (unsigned) encoded / frame_size;
+
+    } while (a2dp->count + (size_t) written <= u->link_mtu);
+
+    /* write it to the fifo */
+    memset(a2dp->buffer, 0, sizeof(*header) + sizeof(*payload));
+    payload->frame_count = a2dp->frame_count;
+    header->v = 2;
+    header->pt = 1;
+    header->sequence_number = htons(a2dp->seq_num);
+    header->timestamp = htonl(a2dp->total_samples);
+    header->ssrc = htonl(1);
+
+    for (;;) {
+        ssize_t l;
+
+        l = pa_loop_write(u->stream_fd, a2dp->buffer, a2dp->count, NULL);
+        pa_log_debug("avdtp_write: requested %lu bytes; written %li bytes", (unsigned long) a2dp->count, (long) l);
+
+        pa_assert(l != 0);
+
+        if (l > 0)
+            break;
+
+        if (errno == EINTR)
+            pa_log_debug("EINTR");
+        else if (errno == EAGAIN)
+            pa_log_debug("EAGAIN");
+        else {
+            pa_log_error("Failed to write data to FIFO: %s", pa_cstrerror(errno));
+            return -1;
+        }
+    }
+
+    u->offset += a2dp->codesize*a2dp->frame_count;
+
+    /* Reset buffer of data to send */
+    a2dp->count = sizeof(struct rtp_header) + sizeof(struct rtp_payload);
+    a2dp->frame_count = 0;
+    a2dp->samples = 0;
+    a2dp->seq_num++;
+
+    return 0;
+}
+
+static void thread_func(void *userdata) {
+    struct userdata *u = userdata;
+
+    pa_assert(u);
+
+    pa_log_debug("IO Thread starting up");
+
+    if (u->core->realtime_scheduling)
+        pa_make_realtime(u->core->realtime_priority);
+
+    pa_thread_mq_install(&u->thread_mq);
+    pa_rtpoll_install(u->rtpoll);
+
+    pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec());
+
+    for (;;) {
+        int ret, l;
+        struct pollfd *pollfd;
+        uint64_t n;
+        pa_usec_t usec;
+
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+            if (u->sink->thread_info.rewind_requested)
+                pa_sink_process_rewind(u->sink, 0);
+
+        pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+
+        if (PA_SINK_IS_OPENED(u->sink->thread_info.state) && pollfd->revents) {
+            if (u->transport == BT_CAPABILITIES_TRANSPORT_A2DP) {
+                if ((l = a2dp_process_render(u)) < 0)
+                    goto fail;
+            } else {
+                if ((l = sco_process_render(u)) < 0)
+                    goto fail;
+            }
+            pollfd->revents = 0;
+
+            /* feed the time smoother */
+            n = u->offset;
+            if (ioctl(u->stream_fd, SIOCOUTQ, &l) >= 0 && l > 0)
+                n -= (uint64_t) l;
+            usec = pa_bytes_to_usec(n, &u->sink->sample_spec);
+            if (usec > u->latency)
+                usec -= u->latency;
+            else
+                usec = 0;
+            pa_smoother_put(u->smoother, pa_rtclock_usec(), usec);
+        }
+
+        /* Hmm, nothing to do. Let's sleep */
+        pa_log_debug("IO thread going to sleep");
+        pollfd->events = (short) (PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0);
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0) {
+            pa_log_error("rtpoll_run < 0");
+            goto fail;
+        }
+        pa_log_debug("IO thread waking up");
+
+        if (ret == 0) {
+            pa_log_debug("rtpoll_run == 0");
+            goto finish;
+        }
+
+        pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+        if (pollfd->revents & ~POLLOUT) {
+            pa_log_error("FIFO shutdown.");
+            goto fail;
+        }
+    }
+
+fail:
+    /* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */
+    pa_log_debug("IO thread failed");
+    pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
+    pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
+
+finish:
+    pa_log_debug("IO thread shutting down");
+}
+
+int pa__init(pa_module* m) {
+    int e;
+    pa_modargs *ma;
+    uint32_t channels;
+    pa_sink_new_data data;
+    struct pollfd *pollfd;
+    struct userdata *u;
+
+    pa_assert(m);
+    m->userdata = u = pa_xnew0(struct userdata, 1);
+    u->module = m;
+    u->core = m->core;
+    u->audioservice_fd = -1;
+    u->stream_fd = -1;
+    u->transport = (uint8_t) -1;
+    u->offset = 0;
+    u->latency = 0;
+    u->a2dp.sbc_initialized = FALSE;
+    u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC*2, TRUE, 10);
+    u->rtpoll = pa_rtpoll_new();
+    pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll);
+    u->rtpoll_item = NULL;
+    u->ss = m->core->default_sample_spec;
+
+    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+        pa_log_error("Failed to parse module arguments");
+        goto fail;
+    }
+    if (!(u->name = pa_xstrdup(pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME)))) {
+        pa_log_error("Failed to get device name from module arguments");
+        goto fail;
+    }
+    if (!(u->addr = pa_xstrdup(pa_modargs_get_value(ma, "address", NULL)))) {
+        pa_log_error("Failed to get device address from module arguments");
+        goto fail;
+    }
+    if (!(u->profile = pa_xstrdup(pa_modargs_get_value(ma, "profile", NULL)))) {
+        pa_log_error("Failed to get profile from module arguments");
+        goto fail;
+    }
+    if (pa_modargs_get_value_u32(ma, "rate", &u->ss.rate) < 0) {
+        pa_log_error("Failed to get rate from module arguments");
+        goto fail;
+    }
+
+    channels = u->ss.channels;
+    if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0) {
+        pa_log_error("Failed to get channels from module arguments");
+        goto fail;
+    }
+    u->ss.channels = (uint8_t) channels;
+
+    /* connect to the bluez audio service */
+    u->audioservice_fd = bt_audio_service_open();
+    if (u->audioservice_fd <= 0) {
+        pa_log_error("Couldn't connect to bluetooth audio service");
+        goto fail;
+    }
+    pa_log_debug("Connected to the bluetooth audio service");
+
+    /* queries device capabilities */
+    e = bt_getcaps(u);
+    if (e < 0) {
+        pa_log_error("Failed to get device capabilities");
+        goto fail;
+    }
+    pa_log_debug("Got device capabilities");
+
+    /* configures the connection */
+    e = bt_setconf(u);
+    if (e < 0) {
+        pa_log_error("Failed to set config");
+        goto fail;
+    }
+    pa_log_debug("Connection to the device configured");
+
+    /* gets the device socket */
+    e = bt_getstreamfd(u);
+    if (e < 0) {
+        pa_log_error("Failed to get stream fd (%d)", e);
+        goto fail;
+    }
+    pa_log_debug("Got the device socket");
+
+    /* create sink */
+    pa_sink_new_data_init(&data);
+    data.driver = __FILE__;
+    data.module = m;
+    pa_sink_new_data_set_name(&data, u->name);
+    pa_sink_new_data_set_sample_spec(&data, &u->ss);
+    pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, u->name);
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Bluetooth %s '%s' (%s)", u->strtransport, u->name, u->addr);
+    pa_proplist_sets(data.proplist, "bluetooth.protocol", u->profile);
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_API, "bluez");
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_CLASS, "sound");
+    pa_proplist_setf(data.proplist, PA_PROP_DEVICE_CONNECTOR, "bluetooth");
+/*     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_FORM_FACTOR, "headset"); /\*FIXME*\/ */
+/*     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_VENDOR_PRODUCT_ID, "product_id"); /\*FIXME*\/ */
+/*     pa_proplist_setf(data.proplist, PA_PROP_DEVICE_SERIAL, "serial"); /\*FIXME*\/ */
+    u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
+    pa_sink_new_data_done(&data);
+    if (!u->sink) {
+        pa_log_error("Failed to create sink");
+        goto fail;
+    }
+    u->sink->userdata = u;
+    u->sink->parent.process_msg = sink_process_msg;
+    pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+    pa_sink_set_rtpoll(u->sink, u->rtpoll);
+
+    u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
+    pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+    pollfd->fd = u->stream_fd;
+    pollfd->events = pollfd->revents = 0;
+
+    /* start rt thread */
+    if (!(u->thread = pa_thread_new(thread_func, u))) {
+        pa_log_error("Failed to create IO thread");
+        goto fail;
+    }
+    pa_sink_put(u->sink);
+
+    pa_modargs_free(ma);
+    return 0;
+
+fail:
+    if (ma)
+        pa_modargs_free(ma);
+
+    pa__done(m);
+    return -1;
+}
+
+void pa__done(pa_module *m) {
+    struct userdata *u;
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    if (u->sink)
+        pa_sink_unlink(u->sink);
+
+    if (u->thread) {
+        pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
+        pa_thread_free(u->thread);
+    }
+
+    if (u->sink)
+        pa_sink_unref(u->sink);
+
+    pa_thread_mq_done(&u->thread_mq);
+
+    if (u->rtpoll_item)
+        pa_rtpoll_item_free(u->rtpoll_item);
+
+    if (u->rtpoll)
+        pa_rtpoll_free(u->rtpoll);
+
+    if (u->smoother)
+        pa_smoother_free(u->smoother);
+
+    pa_xfree(u->name);
+    pa_xfree(u->addr);
+    pa_xfree(u->profile);
+    pa_xfree(u->strtransport);
+
+    if (u->stream_fd >= 0)
+        pa_close(u->stream_fd);
+
+    if (u->audioservice_fd >= 0)
+        pa_close(u->audioservice_fd);
+
+    pa_xfree(u);
+}
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
new file mode 100644 (file)
index 0000000..a33ca64
--- /dev/null
@@ -0,0 +1,543 @@
+/***
+    This file is part of PulseAudio.
+
+    Copyright 2008 Joao Paulo Rechi Vita
+
+    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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pulse/xmalloc.h>
+#include <pulsecore/module.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/llist.h>
+#include <pulsecore/core-util.h>
+
+#include "../dbus-util.h"
+#include "module-bluetooth-discover-symdef.h"
+
+PA_MODULE_AUTHOR("Joao Paulo Rechi Vita");
+PA_MODULE_DESCRIPTION("Detect available bluetooth audio devices and load bluetooth audio drivers");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_USAGE("");
+
+struct module {
+    char *profile;
+    pa_module *pa_m;
+    PA_LLIST_FIELDS(struct module);
+};
+
+struct uuid {
+    char *uuid;
+    PA_LLIST_FIELDS(struct uuid);
+};
+
+struct device {
+    char *name;
+    char *object_path;
+    int paired;
+    char *alias;
+    int connected;
+    PA_LLIST_HEAD(struct uuid, uuid_list);
+    char *address;
+    int class;
+    int trusted;
+    PA_LLIST_HEAD(struct module, module_list);
+    PA_LLIST_FIELDS(struct device);
+};
+
+struct userdata {
+    pa_module *module;
+    pa_dbus_connection *conn;
+    PA_LLIST_HEAD(struct device, device_list);
+};
+
+static struct module *module_new(const char *profile, pa_module *pa_m) {
+    struct module *m;
+
+    m = pa_xnew(struct module, 1);
+    m->profile = pa_xstrdup(profile);
+    m->pa_m = pa_m;
+    PA_LLIST_INIT(struct module, m);
+
+    return m;
+}
+
+static void module_free(struct module *m) {
+    pa_assert(m);
+
+    pa_xfree(m->profile);
+    pa_xfree(m);
+}
+
+static struct module* module_find(struct device *d, const char *profile) {
+    struct module *m;
+
+    for (m = d->module_list; d; d = d->next)
+        if (pa_streq(m->profile, profile))
+            return m;
+
+    return NULL;
+}
+
+static struct uuid *uuid_new(const char *uuid) {
+    struct uuid *node;
+
+    node = pa_xnew(struct uuid, 1);
+    node->uuid = pa_xstrdup(uuid);
+    PA_LLIST_INIT(struct uuid, node);
+
+    return node;
+}
+
+static void uuid_free(struct uuid *uuid) {
+    pa_assert(uuid);
+
+    pa_xfree(uuid->uuid);
+    pa_xfree(uuid);
+}
+
+static struct device *device_new(const char *object_path) {
+    struct device *node;
+
+    node = pa_xnew(struct device, 1);
+    node->name = NULL;
+    node->object_path = pa_xstrdup(object_path);
+    node->paired = -1;
+    node->alias = NULL;
+    node->connected = -1;
+    PA_LLIST_HEAD_INIT(struct uuid, node->uuid_list);
+    node->address = NULL;
+    node->class = -1;
+    node->trusted = -1;
+    PA_LLIST_HEAD_INIT(struct module, node->module_list);
+    PA_LLIST_INIT(struct device, node);
+
+    return node;
+}
+
+static void device_free(struct device *device) {
+    struct module *m;
+    struct uuid *i;
+
+    pa_assert(device);
+
+    while ((m = device->module_list)) {
+        PA_LLIST_REMOVE(struct module, device->module_list, m);
+        module_free(m);
+    }
+
+    while ((i = device->uuid_list)) {
+        PA_LLIST_REMOVE(struct uuid, device->uuid_list, i);
+        uuid_free(i);
+    }
+
+    pa_xfree(device->name);
+    pa_xfree(device->object_path);
+    pa_xfree(device->alias);
+    pa_xfree(device->address);
+    pa_xfree(device);
+}
+
+static struct device* device_find(struct userdata *u, const char *path) {
+    struct device *i;
+
+    for (i = u->device_list; i; i = i->next)
+        if (pa_streq(i->object_path, path))
+            return i;
+
+    return NULL;
+}
+
+static int parse_device_property(struct userdata *u, struct device *d, DBusMessageIter *i) {
+    const char *key;
+    DBusMessageIter variant_i;
+
+    pa_assert(u);
+    pa_assert(d);
+    pa_assert(i);
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
+        pa_log("Property name not a string.");
+        return -1;
+    }
+
+    dbus_message_iter_get_basic(i, &key);
+
+    if (!dbus_message_iter_next(i))  {
+        pa_log("Property value missing");
+        return -1;
+    }
+
+    if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
+        pa_log("Property value not a variant.");
+        return -1;
+    }
+
+    dbus_message_iter_recurse(i, &variant_i);
+
+    pa_log_debug("Parsing device property %s", key);
+
+    switch (dbus_message_iter_get_arg_type(&variant_i)) {
+
+        case DBUS_TYPE_STRING: {
+
+            const char *value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Name")) {
+                pa_xfree(d->name);
+                d->name = pa_xstrdup(value);
+            } else if (pa_streq(key, "Alias")) {
+                pa_xfree(d->alias);
+                d->alias = pa_xstrdup(value);
+            } else if (pa_streq(key, "Address")) {
+                pa_xfree(d->address);
+                d->address = pa_xstrdup(value);
+            }
+
+            break;
+        }
+
+        case DBUS_TYPE_BOOLEAN: {
+
+            dbus_bool_t value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Paired"))
+                d->paired = !!value;
+            else if (pa_streq(key, "Connected"))
+                d->connected = !!value;
+            else if (pa_streq(key, "Trusted"))
+                d->trusted = !!value;
+
+            break;
+        }
+
+        case DBUS_TYPE_UINT32: {
+
+            uint32_t value;
+            dbus_message_iter_get_basic(&variant_i, &value);
+
+            if (pa_streq(key, "Class"))
+                d->class = (int) value;
+
+            break;
+        }
+
+        case DBUS_TYPE_ARRAY: {
+
+            DBusMessageIter ai;
+            dbus_message_iter_recurse(&variant_i, &ai);
+
+            if (dbus_message_iter_get_arg_type(&ai) == DBUS_TYPE_STRING &&
+                pa_streq(key, "UUIDs")) {
+
+                while (dbus_message_iter_get_arg_type(&ai) != DBUS_TYPE_INVALID) {
+                    struct uuid *node;
+                    const char *value;
+
+                    dbus_message_iter_get_basic(&ai, &value);
+                    node = uuid_new(value);
+                    PA_LLIST_PREPEND(struct uuid, d->uuid_list, node);
+
+                    if (!dbus_message_iter_next(&ai))
+                        break;
+                }
+            }
+
+            break;
+        }
+    }
+
+    return 0;
+}
+
+static int get_device_properties(struct userdata *u, struct device *d) {
+    DBusError e;
+    DBusMessage *m = NULL, *r = NULL;
+    DBusMessageIter arg_i, element_i;
+    int ret = -1;
+
+    pa_assert(u);
+    pa_assert(d);
+
+    dbus_error_init(&e);
+
+    pa_assert_se(m = dbus_message_new_method_call("org.bluez", d->object_path, "org.bluez.Device", "GetProperties"));
+
+    r = dbus_connection_send_with_reply_and_block(pa_dbus_connection_get(u->conn), m, -1, &e);
+
+    if (!r) {
+        pa_log("org.bluez.Device.GetProperties failed: %s", e.message);
+        goto finish;
+    }
+
+    if (!dbus_message_iter_init(r, &arg_i)) {
+        pa_log("org.bluez.Device.GetProperties reply has no arguments");
+        goto finish;
+    }
+
+    if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_ARRAY) {
+        pa_log("org.bluez.Device.GetProperties argument is not an array");
+        goto finish;
+    }
+
+    dbus_message_iter_recurse(&arg_i, &element_i);
+    while (dbus_message_iter_get_arg_type(&element_i) != DBUS_TYPE_INVALID) {
+
+        if (dbus_message_iter_get_arg_type(&element_i) == DBUS_TYPE_DICT_ENTRY) {
+            DBusMessageIter dict_i;
+
+            dbus_message_iter_recurse(&element_i, &dict_i);
+
+            if (parse_device_property(u, d, &dict_i) < 0)
+                goto finish;
+        }
+
+        if (!dbus_message_iter_next(&element_i))
+            break;
+    }
+
+    ret = 0;
+
+finish:
+    if (m)
+        dbus_message_unref(m);
+    if (r)
+        dbus_message_unref(r);
+
+    dbus_error_free(&e);
+
+    return ret;
+}
+
+static void load_module_for_device(struct userdata *u, struct device *d, const char *profile) {
+    char *args;
+    pa_module *pa_m;
+    struct module *m;
+
+    pa_assert(u);
+    pa_assert(d);
+
+    get_device_properties(u, d);
+    args = pa_sprintf_malloc("sink_name=\"%s\" address=\"%s\" profile=\"%s\"", d->name, d->address, profile);
+    pa_m = pa_module_load(u->module->core, "module-bluetooth-device", args);
+    pa_xfree(args);
+
+    if (!m) {
+        pa_log_debug("Failed to load module for device %s", d->object_path);
+        return;
+    }
+
+    m = module_new(profile, pa_m);
+    PA_LLIST_PREPEND(struct module, d->module_list, m);
+}
+
+static void unload_module_for_device(struct userdata *u, struct device *d, const char *profile) {
+    struct module *m;
+
+    pa_assert(u);
+    pa_assert(d);
+
+    if (!(m = module_find(d, profile)))
+        return;
+
+    pa_module_unload_request(m->pa_m, TRUE);
+
+    PA_LLIST_REMOVE(struct module, d->module_list, m);
+    module_free(m);
+}
+
+static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *msg, void *userdata) {
+    DBusMessageIter arg_i;
+    DBusError err;
+    const char *value;
+    struct userdata *u;
+
+    pa_assert(bus);
+    pa_assert(msg);
+    pa_assert(userdata);
+    u = userdata;
+
+    dbus_error_init(&err);
+
+    pa_log_debug("dbus: interface=%s, path=%s, member=%s\n",
+            dbus_message_get_interface(msg),
+            dbus_message_get_path(msg),
+            dbus_message_get_member(msg));
+
+    if (dbus_message_is_signal(msg, "org.bluez.Adapter", "DeviceRemoved")) {
+
+        if (!dbus_message_iter_init(msg, &arg_i))
+            pa_log("dbus: message has no parameters");
+        else if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_OBJECT_PATH)
+            pa_log("dbus: argument is not object path");
+        else {
+            struct device *d;
+
+            dbus_message_iter_get_basic(&arg_i, &value);
+            pa_log_debug("hcid: device %s removed", value);
+
+            if ((d = device_find(u, value))) {
+                PA_LLIST_REMOVE(struct device, u->device_list, d);
+                device_free(d);
+            }
+        }
+
+    } else if (dbus_message_is_signal(msg, "org.bluez.Headset", "PropertyChanged") ||
+               dbus_message_is_signal(msg, "org.bluez.AudioSink", "PropertyChanged")) {
+
+        struct device *d;
+        const char *profile;
+        DBusMessageIter variant_i;
+        dbus_bool_t connected;
+
+        if (!dbus_message_iter_init(msg, &arg_i)) {
+            pa_log("dbus: message has no parameters");
+            goto done;
+        }
+
+        if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_STRING) {
+            pa_log("Property name not a string.");
+            goto done;
+        }
+
+        dbus_message_iter_get_basic(&arg_i, &value);
+
+        if (!pa_streq(value, "Connected"))
+            goto done;
+
+        if (!dbus_message_iter_next(&arg_i)) {
+            pa_log("Property value missing");
+            goto done;
+        }
+
+        if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_VARIANT) {
+            pa_log("Property value not a variant.");
+            goto done;
+        }
+
+        dbus_message_iter_recurse(&arg_i, &variant_i);
+
+        if (dbus_message_iter_get_arg_type(&variant_i) != DBUS_TYPE_BOOLEAN) {
+            pa_log("Property value not a boolean.");
+            goto done;
+        }
+
+        dbus_message_iter_get_basic(&variant_i, &connected);
+
+        if (dbus_message_is_signal(msg, "org.bluez.Headset", "PropertyChanged"))
+            profile = "hsp";
+        else
+            profile = "a2dp";
+
+        d = device_find(u, dbus_message_get_path(msg));
+
+        if (connected) {
+            if (!d) {
+                    d = device_new(dbus_message_get_path(msg));
+                    PA_LLIST_PREPEND(struct device, u->device_list, d);
+            }
+
+            load_module_for_device(u, d, profile);
+        } else if (d)
+            unload_module_for_device(u, d, profile);
+    }
+
+done:
+    dbus_error_free(&err);
+    return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+void pa__done(pa_module* m) {
+    struct userdata *u;
+    struct device *i;
+
+    pa_assert(m);
+
+    if (!(u = m->userdata))
+        return;
+
+    while ((i = u->device_list)) {
+        PA_LLIST_REMOVE(struct device, u->device_list, i);
+        device_free(i);
+    }
+
+    if (u->conn)
+        pa_dbus_connection_unref(u->conn);
+
+    pa_xfree(u);
+}
+
+int pa__init(pa_module* m) {
+    DBusError err;
+    struct userdata *u;
+
+    pa_assert(m);
+    dbus_error_init(&err);
+
+    m->userdata = u = pa_xnew(struct userdata, 1);
+    u->module = m;
+    PA_LLIST_HEAD_INIT(struct device, u->device_list);
+
+    /* connect to the bus */
+    u->conn = pa_dbus_bus_get(m->core, DBUS_BUS_SYSTEM, &err);
+    if (dbus_error_is_set(&err) || (u->conn == NULL) ) {
+        pa_log("Failed to get D-Bus connection: %s", err.message);
+        goto fail;
+    }
+
+    /* dynamic detection of bluetooth audio devices */
+    if (!dbus_connection_add_filter(pa_dbus_connection_get(u->conn), filter_cb, u, NULL)) {
+        pa_log_error("Failed to add filter function");
+        goto fail;
+    }
+
+    dbus_bus_add_match(pa_dbus_connection_get(u->conn), "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'", &err);
+    if (dbus_error_is_set(&err)) {
+        pa_log_error("Unable to subscribe to org.bluez.Adapter signals: %s: %s", err.name, err.message);
+        goto fail;
+    }
+
+    dbus_bus_add_match(pa_dbus_connection_get(u->conn), "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'", &err);
+    if (dbus_error_is_set(&err)) {
+        pa_log_error("Unable to subscribe to org.bluez.Headset signals: %s: %s", err.name, err.message);
+        goto fail;
+    }
+
+    dbus_bus_add_match(pa_dbus_connection_get(u->conn), "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", &err);
+    if (dbus_error_is_set(&err)) {
+        pa_log_error("Unable to subscribe to org.bluez.AudioSink signals: %s: %s", err.name, err.message);
+        goto fail;
+    }
+
+    return 0;
+
+fail:
+    dbus_error_free(&err);
+    pa__done(m);
+
+    return -1;
+}
similarity index 99%
rename from src/modules/module-bt-proximity.c
rename to src/modules/bluetooth/module-bluetooth-proximity.c
index f924c3cb4eb0d76709a36ea26cc857ea69706113..4cfaaf5be37435644b281fe4d1856bb61b5d28bc 100644 (file)
@@ -43,8 +43,8 @@
 #include <pulsecore/core-error.h>
 #include <pulsecore/start-child.h>
 
-#include "dbus-util.h"
-#include "module-bt-proximity-symdef.h"
+#include "../dbus-util.h"
+#include "module-bluetooth-proximity-symdef.h"
 
 PA_MODULE_AUTHOR("Lennart Poettering");
 PA_MODULE_DESCRIPTION("Bluetooth Proximity Volume Control");
diff --git a/src/modules/bluetooth/rtp.h b/src/modules/bluetooth/rtp.h
new file mode 100644 (file)
index 0000000..690bd43
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+struct rtp_header {
+       uint8_t cc:4;
+       uint8_t x:1;
+       uint8_t p:1;
+       uint8_t v:2;
+
+       uint8_t pt:7;
+       uint8_t m:1;
+
+       uint16_t sequence_number;
+       uint32_t timestamp;
+       uint32_t ssrc;
+       uint32_t csrc[0];
+} __attribute__ ((packed));
+
+struct rtp_payload {
+       uint8_t frame_count:4;
+       uint8_t rfa0:1;
+       uint8_t is_last_fragment:1;
+       uint8_t is_first_fragment:1;
+       uint8_t is_fragmented:1;
+} __attribute__ ((packed));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+struct rtp_header {
+       uint8_t v:2;
+       uint8_t p:1;
+       uint8_t x:1;
+       uint8_t cc:4;
+
+       uint8_t m:1;
+       uint8_t pt:7;
+
+       uint16_t sequence_number;
+       uint32_t timestamp;
+       uint32_t ssrc;
+       uint32_t csrc[0];
+} __attribute__ ((packed));
+
+struct rtp_payload {
+       uint8_t is_fragmented:1;
+       uint8_t is_first_fragment:1;
+       uint8_t is_last_fragment:1;
+       uint8_t rfa0:1;
+       uint8_t frame_count:4;
+} __attribute__ ((packed));
+
+#else
+#error "Unknown byte order"
+#endif
diff --git a/src/modules/bluetooth/sbc.c b/src/modules/bluetooth/sbc.c
new file mode 100644 (file)
index 0000000..02a6143
--- /dev/null
@@ -0,0 +1,1411 @@
+/*
+ *
+ *  Bluetooth low-complexity, subband codec (SBC) library
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
+ *  Copyright (C) 2005-2008  Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+/* todo items:
+
+  use a log2 table for byte integer scale factors calculation (sum log2 results
+  for high and low bytes) fill bitpool by 16 bits instead of one at a time in
+  bits allocation/bitpool generation port to the dsp
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include "sbc_math.h"
+#include "sbc_tables.h"
+
+#include "sbc.h"
+
+#define SBC_SYNCWORD   0x9C
+
+/* This structure contains an unpacked SBC frame.
+   Yes, there is probably quite some unused space herein */
+struct sbc_frame {
+       uint8_t frequency;
+       uint8_t block_mode;
+       uint8_t blocks;
+       enum {
+               MONO            = SBC_MODE_MONO,
+               DUAL_CHANNEL    = SBC_MODE_DUAL_CHANNEL,
+               STEREO          = SBC_MODE_STEREO,
+               JOINT_STEREO    = SBC_MODE_JOINT_STEREO
+       } mode;
+       uint8_t channels;
+       enum {
+               LOUDNESS        = SBC_AM_LOUDNESS,
+               SNR             = SBC_AM_SNR
+       } allocation;
+       uint8_t subband_mode;
+       uint8_t subbands;
+       uint8_t bitpool;
+       uint8_t codesize;
+       uint8_t length;
+
+       /* bit number x set means joint stereo has been used in subband x */
+       uint8_t joint;
+
+       /* only the lower 4 bits of every element are to be used */
+       uint8_t scale_factor[2][8];
+
+       /* raw integer subband samples in the frame */
+
+       int32_t sb_sample_f[16][2][8];
+       int32_t sb_sample[16][2][8];    /* modified subband samples */
+       int16_t pcm_sample[2][16*8];    /* original pcm audio samples */
+};
+
+struct sbc_decoder_state {
+       int subbands;
+       int32_t V[2][170];
+       int offset[2][16];
+};
+
+struct sbc_encoder_state {
+       int subbands;
+       int position[2];
+       int32_t X[2][160];
+};
+
+/*
+ * Calculates the CRC-8 of the first len bits in data
+ */
+static const uint8_t crc_table[256] = {
+       0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53,
+       0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
+       0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E,
+       0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
+       0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4,
+       0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
+       0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19,
+       0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
+       0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40,
+       0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
+       0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D,
+       0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
+       0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7,
+       0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
+       0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A,
+       0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
+       0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75,
+       0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
+       0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8,
+       0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
+       0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2,
+       0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
+       0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F,
+       0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
+       0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66,
+       0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
+       0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB,
+       0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
+       0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1,
+       0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
+       0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C,
+       0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
+};
+
+static uint8_t sbc_crc8(const uint8_t *data, size_t len)
+{
+       uint8_t crc = 0x0f;
+       size_t i;
+       uint8_t octet;
+
+       for (i = 0; i < len / 8; i++)
+               crc = crc_table[crc ^ data[i]];
+
+       octet = data[i];
+       for (i = 0; i < len % 8; i++) {
+               unsigned char bit = ((octet ^ crc) & 0x80) >> 7;
+
+               crc = ((crc & 0x7f) << 1) ^ (bit ? 0x1d : 0);
+
+               octet = octet << 1;
+       }
+
+       return crc;
+}
+
+/*
+ * Code straight from the spec to calculate the bits array
+ * Takes a pointer to the frame in question, a pointer to the bits array and
+ * the sampling frequency (as 2 bit integer)
+ */
+static void sbc_calculate_bits(const struct sbc_frame *frame, int (*bits)[8])
+{
+       uint8_t sf = frame->frequency;
+
+       if (frame->mode == MONO || frame->mode == DUAL_CHANNEL) {
+               int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
+               int ch, sb;
+
+               for (ch = 0; ch < frame->channels; ch++) {
+                       max_bitneed = 0;
+                       if (frame->allocation == SNR) {
+                               for (sb = 0; sb < frame->subbands; sb++) {
+                                       bitneed[ch][sb] = frame->scale_factor[ch][sb];
+                                       if (bitneed[ch][sb] > max_bitneed)
+                                               max_bitneed = bitneed[ch][sb];
+                               }
+                       } else {
+                               for (sb = 0; sb < frame->subbands; sb++) {
+                                       if (frame->scale_factor[ch][sb] == 0)
+                                               bitneed[ch][sb] = -5;
+                                       else {
+                                               if (frame->subbands == 4)
+                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
+                                               else
+                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
+                                               if (loudness > 0)
+                                                       bitneed[ch][sb] = loudness / 2;
+                                               else
+                                                       bitneed[ch][sb] = loudness;
+                                       }
+                                       if (bitneed[ch][sb] > max_bitneed)
+                                               max_bitneed = bitneed[ch][sb];
+                               }
+                       }
+
+                       bitcount = 0;
+                       slicecount = 0;
+                       bitslice = max_bitneed + 1;
+                       do {
+                               bitslice--;
+                               bitcount += slicecount;
+                               slicecount = 0;
+                               for (sb = 0; sb < frame->subbands; sb++) {
+                                       if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+                                               slicecount++;
+                                       else if (bitneed[ch][sb] == bitslice + 1)
+                                               slicecount += 2;
+                               }
+                       } while (bitcount + slicecount < frame->bitpool);
+
+                       if (bitcount + slicecount == frame->bitpool) {
+                               bitcount += slicecount;
+                               bitslice--;
+                       }
+
+                       for (sb = 0; sb < frame->subbands; sb++) {
+                               if (bitneed[ch][sb] < bitslice + 2)
+                                       bits[ch][sb] = 0;
+                               else {
+                                       bits[ch][sb] = bitneed[ch][sb] - bitslice;
+                                       if (bits[ch][sb] > 16)
+                                               bits[ch][sb] = 16;
+                               }
+                       }
+
+                       for (sb = 0; bitcount < frame->bitpool && sb < frame->subbands; sb++) {
+                               if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) {
+                                       bits[ch][sb]++;
+                                       bitcount++;
+                               } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) {
+                                       bits[ch][sb] = 2;
+                                       bitcount += 2;
+                               }
+                       }
+
+                       for (sb = 0; bitcount < frame->bitpool && sb < frame->subbands; sb++) {
+                               if (bits[ch][sb] < 16) {
+                                       bits[ch][sb]++;
+                                       bitcount++;
+                               }
+                       }
+
+               }
+
+       } else if (frame->mode == STEREO || frame->mode == JOINT_STEREO) {
+               int bitneed[2][8], loudness, max_bitneed, bitcount, slicecount, bitslice;
+               int ch, sb;
+
+               max_bitneed = 0;
+               if (frame->allocation == SNR) {
+                       for (ch = 0; ch < 2; ch++) {
+                               for (sb = 0; sb < frame->subbands; sb++) {
+                                       bitneed[ch][sb] = frame->scale_factor[ch][sb];
+                                       if (bitneed[ch][sb] > max_bitneed)
+                                               max_bitneed = bitneed[ch][sb];
+                               }
+                       }
+               } else {
+                       for (ch = 0; ch < 2; ch++) {
+                               for (sb = 0; sb < frame->subbands; sb++) {
+                                       if (frame->scale_factor[ch][sb] == 0)
+                                               bitneed[ch][sb] = -5;
+                                       else {
+                                               if (frame->subbands == 4)
+                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset4[sf][sb];
+                                               else
+                                                       loudness = frame->scale_factor[ch][sb] - sbc_offset8[sf][sb];
+                                               if (loudness > 0)
+                                                       bitneed[ch][sb] = loudness / 2;
+                                               else
+                                                       bitneed[ch][sb] = loudness;
+                                       }
+                                       if (bitneed[ch][sb] > max_bitneed)
+                                               max_bitneed = bitneed[ch][sb];
+                               }
+                       }
+               }
+
+               bitcount = 0;
+               slicecount = 0;
+               bitslice = max_bitneed + 1;
+               do {
+                       bitslice--;
+                       bitcount += slicecount;
+                       slicecount = 0;
+                       for (ch = 0; ch < 2; ch++) {
+                               for (sb = 0; sb < frame->subbands; sb++) {
+                                       if ((bitneed[ch][sb] > bitslice + 1) && (bitneed[ch][sb] < bitslice + 16))
+                                               slicecount++;
+                                       else if (bitneed[ch][sb] == bitslice + 1)
+                                               slicecount += 2;
+                               }
+                       }
+               } while (bitcount + slicecount < frame->bitpool);
+
+               if (bitcount + slicecount == frame->bitpool) {
+                       bitcount += slicecount;
+                       bitslice--;
+               }
+
+               for (ch = 0; ch < 2; ch++) {
+                       for (sb = 0; sb < frame->subbands; sb++) {
+                               if (bitneed[ch][sb] < bitslice + 2) {
+                                       bits[ch][sb] = 0;
+                               } else {
+                                       bits[ch][sb] = bitneed[ch][sb] - bitslice;
+                                       if (bits[ch][sb] > 16)
+                                               bits[ch][sb] = 16;
+                               }
+                       }
+               }
+
+               ch = 0;
+               sb = 0;
+               while (bitcount < frame->bitpool) {
+                       if ((bits[ch][sb] >= 2) && (bits[ch][sb] < 16)) {
+                               bits[ch][sb]++;
+                               bitcount++;
+                       } else if ((bitneed[ch][sb] == bitslice + 1) && (frame->bitpool > bitcount + 1)) {
+                               bits[ch][sb] = 2;
+                               bitcount += 2;
+                       }
+                       if (ch == 1) {
+                               ch = 0;
+                               sb++;
+                               if (sb >= frame->subbands) break;
+                       } else
+                               ch = 1;
+               }
+
+               ch = 0;
+               sb = 0;
+               while (bitcount < frame->bitpool) {
+                       if (bits[ch][sb] < 16) {
+                               bits[ch][sb]++;
+                               bitcount++;
+                       }
+                       if (ch == 1) {
+                               ch = 0;
+                               sb++;
+                               if (sb >= frame->subbands) break;
+                       } else
+                               ch = 1;
+               }
+
+       }
+
+}
+
+/*
+ * Unpacks a SBC frame at the beginning of the stream in data,
+ * which has at most len bytes into frame.
+ * Returns the length in bytes of the packed frame, or a negative
+ * value on error. The error codes are:
+ *
+ *  -1   Data stream too short
+ *  -2   Sync byte incorrect
+ *  -3   CRC8 incorrect
+ *  -4   Bitpool value out of bounds
+ */
+static int sbc_unpack_frame(const uint8_t *data, struct sbc_frame *frame,
+                               size_t len)
+{
+       int consumed;
+       /* Will copy the parts of the header that are relevant to crc
+        * calculation here */
+       uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+       int crc_pos = 0;
+       int32_t temp;
+
+       int audio_sample;
+       int ch, sb, blk, bit;   /* channel, subband, block and bit standard
+                                  counters */
+       int bits[2][8];         /* bits distribution */
+       uint32_t levels[2][8];  /* levels derived from that */
+
+       if (len < 4)
+               return -1;
+
+       if (data[0] != SBC_SYNCWORD)
+               return -2;
+
+       frame->frequency = (data[1] >> 6) & 0x03;
+
+       frame->block_mode = (data[1] >> 4) & 0x03;
+       switch (frame->block_mode) {
+       case SBC_BLK_4:
+               frame->blocks = 4;
+               break;
+       case SBC_BLK_8:
+               frame->blocks = 8;
+               break;
+       case SBC_BLK_12:
+               frame->blocks = 12;
+               break;
+       case SBC_BLK_16:
+               frame->blocks = 16;
+               break;
+       }
+
+       frame->mode = (data[1] >> 2) & 0x03;
+       switch (frame->mode) {
+       case MONO:
+               frame->channels = 1;
+               break;
+       case DUAL_CHANNEL:      /* fall-through */
+       case STEREO:
+       case JOINT_STEREO:
+               frame->channels = 2;
+               break;
+       }
+
+       frame->allocation = (data[1] >> 1) & 0x01;
+
+       frame->subband_mode = (data[1] & 0x01);
+       frame->subbands = frame->subband_mode ? 8 : 4;
+
+       frame->bitpool = data[2];
+
+       if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
+                       frame->bitpool > 16 * frame->subbands)
+               return -4;
+
+       if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
+                       frame->bitpool > 32 * frame->subbands)
+               return -4;
+
+       /* data[3] is crc, we're checking it later */
+
+       consumed = 32;
+
+       crc_header[0] = data[1];
+       crc_header[1] = data[2];
+       crc_pos = 16;
+
+       if (frame->mode == JOINT_STEREO) {
+               if (len * 8 < consumed + frame->subbands)
+                       return -1;
+
+               frame->joint = 0x00;
+               for (sb = 0; sb < frame->subbands - 1; sb++)
+                       frame->joint |= ((data[4] >> (7 - sb)) & 0x01) << sb;
+               if (frame->subbands == 4)
+                       crc_header[crc_pos / 8] = data[4] & 0xf0;
+               else
+                       crc_header[crc_pos / 8] = data[4];
+
+               consumed += frame->subbands;
+               crc_pos += frame->subbands;
+       }
+
+       if (len * 8 < consumed + (4 * frame->subbands * frame->channels))
+               return -1;
+
+       for (ch = 0; ch < frame->channels; ch++) {
+               for (sb = 0; sb < frame->subbands; sb++) {
+                       /* FIXME assert(consumed % 4 == 0); */
+                       frame->scale_factor[ch][sb] =
+                               (data[consumed >> 3] >> (4 - (consumed & 0x7))) & 0x0F;
+                       crc_header[crc_pos >> 3] |=
+                               frame->scale_factor[ch][sb] << (4 - (crc_pos & 0x7));
+
+                       consumed += 4;
+                       crc_pos += 4;
+               }
+       }
+
+       if (data[3] != sbc_crc8(crc_header, crc_pos))
+               return -3;
+
+       sbc_calculate_bits(frame, bits);
+
+       for (ch = 0; ch < frame->channels; ch++) {
+               for (sb = 0; sb < frame->subbands; sb++)
+                       levels[ch][sb] = (1 << bits[ch][sb]) - 1;
+       }
+
+       for (blk = 0; blk < frame->blocks; blk++) {
+               for (ch = 0; ch < frame->channels; ch++) {
+                       for (sb = 0; sb < frame->subbands; sb++) {
+                               if (levels[ch][sb] > 0) {
+                                       audio_sample = 0;
+                                       for (bit = 0; bit < bits[ch][sb]; bit++) {
+                                               if (consumed > len * 8)
+                                                       return -1;
+
+                                               if ((data[consumed >> 3] >> (7 - (consumed & 0x7))) & 0x01)
+                                                       audio_sample |= 1 << (bits[ch][sb] - bit - 1);
+
+                                               consumed++;
+                                       }
+
+                                       frame->sb_sample[blk][ch][sb] =
+                                               (((audio_sample << 1) | 1) << frame->scale_factor[ch][sb]) /
+                                               levels[ch][sb] - (1 << frame->scale_factor[ch][sb]);
+                               } else
+                                       frame->sb_sample[blk][ch][sb] = 0;
+                       }
+               }
+       }
+
+       if (frame->mode == JOINT_STEREO) {
+               for (blk = 0; blk < frame->blocks; blk++) {
+                       for (sb = 0; sb < frame->subbands; sb++) {
+                               if (frame->joint & (0x01 << sb)) {
+                                       temp = frame->sb_sample[blk][0][sb] +
+                                               frame->sb_sample[blk][1][sb];
+                                       frame->sb_sample[blk][1][sb] =
+                                               frame->sb_sample[blk][0][sb] -
+                                               frame->sb_sample[blk][1][sb];
+                                       frame->sb_sample[blk][0][sb] = temp;
+                               }
+                       }
+               }
+       }
+
+       if ((consumed & 0x7) != 0)
+               consumed += 8 - (consumed & 0x7);
+
+       return consumed >> 3;
+}
+
+static void sbc_decoder_init(struct sbc_decoder_state *state,
+                               const struct sbc_frame *frame)
+{
+       int i, ch;
+
+       memset(state->V, 0, sizeof(state->V));
+       state->subbands = frame->subbands;
+
+       for (ch = 0; ch < 2; ch++)
+               for (i = 0; i < frame->subbands * 2; i++)
+                       state->offset[ch][i] = (10 * i + 10);
+}
+
+static inline void sbc_synthesize_four(struct sbc_decoder_state *state,
+                               struct sbc_frame *frame, int ch, int blk)
+{
+       int i, k, idx;
+       int32_t *v = state->V[ch];
+       int *offset = state->offset[ch];
+
+       for (i = 0; i < 8; i++) {
+               /* Shifting */
+               offset[i]--;
+               if (offset[i] < 0) {
+                       offset[i] = 79;
+                       memcpy(v + 80, v, 9 * sizeof(*v));
+               }
+
+               /* Distribute the new matrix value to the shifted position */
+               v[offset[i]] = SCALE4_STAGED1(
+                       MULA(synmatrix4[i][0], frame->sb_sample[blk][ch][0],
+                       MULA(synmatrix4[i][1], frame->sb_sample[blk][ch][1],
+                       MULA(synmatrix4[i][2], frame->sb_sample[blk][ch][2],
+                       MUL (synmatrix4[i][3], frame->sb_sample[blk][ch][3])))));
+       }
+
+       /* Compute the samples */
+       for (idx = 0, i = 0; i < 4; i++, idx += 5) {
+               k = (i + 4) & 0xf;
+
+               /* Store in output, Q0 */
+               frame->pcm_sample[ch][blk * 4 + i] = SCALE4_STAGED2(
+                       MULA(v[offset[i] + 0], sbc_proto_4_40m0[idx + 0],
+                       MULA(v[offset[k] + 1], sbc_proto_4_40m1[idx + 0],
+                       MULA(v[offset[i] + 2], sbc_proto_4_40m0[idx + 1],
+                       MULA(v[offset[k] + 3], sbc_proto_4_40m1[idx + 1],
+                       MULA(v[offset[i] + 4], sbc_proto_4_40m0[idx + 2],
+                       MULA(v[offset[k] + 5], sbc_proto_4_40m1[idx + 2],
+                       MULA(v[offset[i] + 6], sbc_proto_4_40m0[idx + 3],
+                       MULA(v[offset[k] + 7], sbc_proto_4_40m1[idx + 3],
+                       MULA(v[offset[i] + 8], sbc_proto_4_40m0[idx + 4],
+                       MUL( v[offset[k] + 9], sbc_proto_4_40m1[idx + 4])))))))))));
+       }
+}
+
+static inline void sbc_synthesize_eight(struct sbc_decoder_state *state,
+                               struct sbc_frame *frame, int ch, int blk)
+{
+       int i, j, k, idx;
+       int *offset = state->offset[ch];
+
+       for (i = 0; i < 16; i++) {
+               /* Shifting */
+               offset[i]--;
+               if (offset[i] < 0) {
+                       offset[i] = 159;
+                       for (j = 0; j < 9; j++)
+                               state->V[ch][j + 160] = state->V[ch][j];
+               }
+
+               /* Distribute the new matrix value to the shifted position */
+               state->V[ch][offset[i]] = SCALE8_STAGED1(
+                       MULA(synmatrix8[i][0], frame->sb_sample[blk][ch][0],
+                       MULA(synmatrix8[i][1], frame->sb_sample[blk][ch][1],
+                       MULA(synmatrix8[i][2], frame->sb_sample[blk][ch][2],
+                       MULA(synmatrix8[i][3], frame->sb_sample[blk][ch][3],
+                       MULA(synmatrix8[i][4], frame->sb_sample[blk][ch][4],
+                       MULA(synmatrix8[i][5], frame->sb_sample[blk][ch][5],
+                       MULA(synmatrix8[i][6], frame->sb_sample[blk][ch][6],
+                       MUL( synmatrix8[i][7], frame->sb_sample[blk][ch][7])))))))));
+       }
+
+       /* Compute the samples */
+       for (idx = 0, i = 0; i < 8; i++, idx += 5) {
+               k = (i + 8) & 0xf;
+
+               /* Store in output */
+               frame->pcm_sample[ch][blk * 8 + i] = SCALE8_STAGED2( // Q0
+                       MULA(state->V[ch][offset[i] + 0], sbc_proto_8_80m0[idx + 0],
+                       MULA(state->V[ch][offset[k] + 1], sbc_proto_8_80m1[idx + 0],
+                       MULA(state->V[ch][offset[i] + 2], sbc_proto_8_80m0[idx + 1],
+                       MULA(state->V[ch][offset[k] + 3], sbc_proto_8_80m1[idx + 1],
+                       MULA(state->V[ch][offset[i] + 4], sbc_proto_8_80m0[idx + 2],
+                       MULA(state->V[ch][offset[k] + 5], sbc_proto_8_80m1[idx + 2],
+                       MULA(state->V[ch][offset[i] + 6], sbc_proto_8_80m0[idx + 3],
+                       MULA(state->V[ch][offset[k] + 7], sbc_proto_8_80m1[idx + 3],
+                       MULA(state->V[ch][offset[i] + 8], sbc_proto_8_80m0[idx + 4],
+                       MUL( state->V[ch][offset[k] + 9], sbc_proto_8_80m1[idx + 4])))))))))));
+       }
+}
+
+static int sbc_synthesize_audio(struct sbc_decoder_state *state,
+                               struct sbc_frame *frame)
+{
+       int ch, blk;
+
+       switch (frame->subbands) {
+       case 4:
+               for (ch = 0; ch < frame->channels; ch++) {
+                       for (blk = 0; blk < frame->blocks; blk++)
+                               sbc_synthesize_four(state, frame, ch, blk);
+               }
+               return frame->blocks * 4;
+
+       case 8:
+               for (ch = 0; ch < frame->channels; ch++) {
+                       for (blk = 0; blk < frame->blocks; blk++)
+                               sbc_synthesize_eight(state, frame, ch, blk);
+               }
+               return frame->blocks * 8;
+
+       default:
+               return -EIO;
+       }
+}
+
+static void sbc_encoder_init(struct sbc_encoder_state *state,
+                               const struct sbc_frame *frame)
+{
+       memset(&state->X, 0, sizeof(state->X));
+       state->subbands = frame->subbands;
+       state->position[0] = state->position[1] = 9 * frame->subbands;
+}
+
+static inline void _sbc_analyze_four(const int32_t *in, int32_t *out)
+{
+       sbc_fixed_t t[8], s[5];
+
+       t[0] = SCALE4_STAGE1( /* Q8 */
+               MULA(_sbc_proto_4[0], in[8] - in[32], /* Q18 */
+               MUL( _sbc_proto_4[1], in[16] - in[24])));
+
+       t[1] = SCALE4_STAGE1(
+               MULA(_sbc_proto_4[2], in[1],
+               MULA(_sbc_proto_4[3], in[9],
+               MULA(_sbc_proto_4[4], in[17],
+               MULA(_sbc_proto_4[5], in[25],
+               MUL( _sbc_proto_4[6], in[33]))))));
+
+       t[2] = SCALE4_STAGE1(
+               MULA(_sbc_proto_4[7], in[2],
+               MULA(_sbc_proto_4[8], in[10],
+               MULA(_sbc_proto_4[9], in[18],
+               MULA(_sbc_proto_4[10], in[26],
+               MUL( _sbc_proto_4[11], in[34]))))));
+
+       t[3] = SCALE4_STAGE1(
+               MULA(_sbc_proto_4[12], in[3],
+               MULA(_sbc_proto_4[13], in[11],
+               MULA(_sbc_proto_4[14], in[19],
+               MULA(_sbc_proto_4[15], in[27],
+               MUL( _sbc_proto_4[16], in[35]))))));
+
+       t[4] = SCALE4_STAGE1(
+               MULA(_sbc_proto_4[17], in[4] + in[36],
+               MULA(_sbc_proto_4[18], in[12] + in[28],
+               MUL( _sbc_proto_4[19], in[20]))));
+
+       t[5] = SCALE4_STAGE1(
+               MULA(_sbc_proto_4[16], in[5],
+               MULA(_sbc_proto_4[15], in[13],
+               MULA(_sbc_proto_4[14], in[21],
+               MULA(_sbc_proto_4[13], in[29],
+               MUL( _sbc_proto_4[12], in[37]))))));
+
+       /* don't compute t[6]... this term always multiplies
+        * with cos(pi/2) = 0 */
+
+       t[7] = SCALE4_STAGE1(
+               MULA(_sbc_proto_4[6], in[7],
+               MULA(_sbc_proto_4[5], in[15],
+               MULA(_sbc_proto_4[4], in[23],
+               MULA(_sbc_proto_4[3], in[31],
+               MUL( _sbc_proto_4[2], in[39]))))));
+
+       s[0] = MUL( _anamatrix4[0], t[0] + t[4]);
+       s[1] = MUL( _anamatrix4[2], t[2]);
+       s[2] = MULA(_anamatrix4[1], t[1] + t[3],
+               MUL(_anamatrix4[3], t[5]));
+       s[3] = MULA(_anamatrix4[3], t[1] + t[3],
+               MUL(_anamatrix4[1], -t[5] + t[7]));
+       s[4] = MUL( _anamatrix4[3], t[7]);
+
+       out[0] = SCALE4_STAGE2( s[0] + s[1] + s[2] + s[4]); /* Q0 */
+       out[1] = SCALE4_STAGE2(-s[0] + s[1] + s[3]);
+       out[2] = SCALE4_STAGE2(-s[0] + s[1] - s[3]);
+       out[3] = SCALE4_STAGE2( s[0] + s[1] - s[2] - s[4]);
+}
+
+static inline void sbc_analyze_four(struct sbc_encoder_state *state,
+                               struct sbc_frame *frame, int ch, int blk)
+{
+       int32_t *x = &state->X[ch][state->position[ch]];
+       int16_t *pcm = &frame->pcm_sample[ch][blk * 4];
+
+       /* Input 4 Audio Samples */
+       x[40] = x[0] = pcm[3];
+       x[41] = x[1] = pcm[2];
+       x[42] = x[2] = pcm[1];
+       x[43] = x[3] = pcm[0];
+
+       _sbc_analyze_four(x, frame->sb_sample_f[blk][ch]);
+
+       state->position[ch] -= 4;
+       if (state->position[ch] < 0)
+               state->position[ch] = 36;
+}
+
+static inline void _sbc_analyze_eight(const int32_t *in, int32_t *out)
+{
+       sbc_fixed_t t[8], s[8];
+
+       t[0] = SCALE8_STAGE1( /* Q10 */
+               MULA(_sbc_proto_8[0], (in[16] - in[64]), /* Q18 = Q18 * Q0 */
+               MULA(_sbc_proto_8[1], (in[32] - in[48]),
+               MULA(_sbc_proto_8[2], in[4],
+               MULA(_sbc_proto_8[3], in[20],
+               MULA(_sbc_proto_8[4], in[36],
+               MUL( _sbc_proto_8[5], in[52])))))));
+
+       t[1] = SCALE8_STAGE1(
+               MULA(_sbc_proto_8[6], in[2],
+               MULA(_sbc_proto_8[7], in[18],
+               MULA(_sbc_proto_8[8], in[34],
+               MULA(_sbc_proto_8[9], in[50],
+               MUL(_sbc_proto_8[10], in[66]))))));
+
+       t[2] = SCALE8_STAGE1(
+               MULA(_sbc_proto_8[11], in[1],
+               MULA(_sbc_proto_8[12], in[17],
+               MULA(_sbc_proto_8[13], in[33],
+               MULA(_sbc_proto_8[14], in[49],
+               MULA(_sbc_proto_8[15], in[65],
+               MULA(_sbc_proto_8[16], in[3],
+               MULA(_sbc_proto_8[17], in[19],
+               MULA(_sbc_proto_8[18], in[35],
+               MULA(_sbc_proto_8[19], in[51],
+               MUL( _sbc_proto_8[20], in[67])))))))))));
+
+       t[3] = SCALE8_STAGE1(
+               MULA( _sbc_proto_8[21], in[5],
+               MULA( _sbc_proto_8[22], in[21],
+               MULA( _sbc_proto_8[23], in[37],
+               MULA( _sbc_proto_8[24], in[53],
+               MULA( _sbc_proto_8[25], in[69],
+               MULA(-_sbc_proto_8[15], in[15],
+               MULA(-_sbc_proto_8[14], in[31],
+               MULA(-_sbc_proto_8[13], in[47],
+               MULA(-_sbc_proto_8[12], in[63],
+               MUL( -_sbc_proto_8[11], in[79])))))))))));
+
+       t[4] = SCALE8_STAGE1(
+               MULA( _sbc_proto_8[26], in[6],
+               MULA( _sbc_proto_8[27], in[22],
+               MULA( _sbc_proto_8[28], in[38],
+               MULA( _sbc_proto_8[29], in[54],
+               MULA( _sbc_proto_8[30], in[70],
+               MULA(-_sbc_proto_8[10], in[14],
+               MULA(-_sbc_proto_8[9], in[30],
+               MULA(-_sbc_proto_8[8], in[46],
+               MULA(-_sbc_proto_8[7], in[62],
+               MUL( -_sbc_proto_8[6], in[78])))))))))));
+
+       t[5] = SCALE8_STAGE1(
+               MULA( _sbc_proto_8[31], in[7],
+               MULA( _sbc_proto_8[32], in[23],
+               MULA( _sbc_proto_8[33], in[39],
+               MULA( _sbc_proto_8[34], in[55],
+               MULA( _sbc_proto_8[35], in[71],
+               MULA(-_sbc_proto_8[20], in[13],
+               MULA(-_sbc_proto_8[19], in[29],
+               MULA(-_sbc_proto_8[18], in[45],
+               MULA(-_sbc_proto_8[17], in[61],
+               MUL( -_sbc_proto_8[16], in[77])))))))))));
+
+       t[6] = SCALE8_STAGE1(
+               MULA( _sbc_proto_8[36], (in[8] + in[72]),
+               MULA( _sbc_proto_8[37], (in[24] + in[56]),
+               MULA( _sbc_proto_8[38], in[40],
+               MULA(-_sbc_proto_8[39], in[12],
+               MULA(-_sbc_proto_8[5], in[28],
+               MULA(-_sbc_proto_8[4], in[44],
+               MULA(-_sbc_proto_8[3], in[60],
+               MUL( -_sbc_proto_8[2], in[76])))))))));
+
+       t[7] = SCALE8_STAGE1(
+               MULA( _sbc_proto_8[35], in[9],
+               MULA( _sbc_proto_8[34], in[25],
+               MULA( _sbc_proto_8[33], in[41],
+               MULA( _sbc_proto_8[32], in[57],
+               MULA( _sbc_proto_8[31], in[73],
+               MULA(-_sbc_proto_8[25], in[11],
+               MULA(-_sbc_proto_8[24], in[27],
+               MULA(-_sbc_proto_8[23], in[43],
+               MULA(-_sbc_proto_8[22], in[59],
+               MUL( -_sbc_proto_8[21], in[75])))))))))));
+
+       s[0] = MULA(  _anamatrix8[0], t[0],
+               MUL(  _anamatrix8[1], t[6]));
+       s[1] = MUL(   _anamatrix8[7], t[1]);
+       s[2] = MULA(  _anamatrix8[2], t[2],
+               MULA( _anamatrix8[3], t[3],
+               MULA( _anamatrix8[4], t[5],
+               MUL(  _anamatrix8[5], t[7]))));
+       s[3] = MUL(   _anamatrix8[6], t[4]);
+       s[4] = MULA(  _anamatrix8[3], t[2],
+               MULA(-_anamatrix8[5], t[3],
+               MULA(-_anamatrix8[2], t[5],
+               MUL( -_anamatrix8[4], t[7]))));
+       s[5] = MULA(  _anamatrix8[4], t[2],
+               MULA(-_anamatrix8[2], t[3],
+               MULA( _anamatrix8[5], t[5],
+               MUL(  _anamatrix8[3], t[7]))));
+       s[6] = MULA(  _anamatrix8[1], t[0],
+               MUL( -_anamatrix8[0], t[6]));
+       s[7] = MULA(  _anamatrix8[5], t[2],
+               MULA(-_anamatrix8[4], t[3],
+               MULA( _anamatrix8[3], t[5],
+               MUL( -_anamatrix8[2], t[7]))));
+
+       out[0] = SCALE8_STAGE2( s[0] + s[1] + s[2] + s[3]);
+       out[1] = SCALE8_STAGE2( s[1] - s[3] + s[4] + s[6]);
+       out[2] = SCALE8_STAGE2( s[1] - s[3] + s[5] - s[6]);
+       out[3] = SCALE8_STAGE2(-s[0] + s[1] + s[3] + s[7]);
+       out[4] = SCALE8_STAGE2(-s[0] + s[1] + s[3] - s[7]);
+       out[5] = SCALE8_STAGE2( s[1] - s[3] - s[5] - s[6]);
+       out[6] = SCALE8_STAGE2( s[1] - s[3] - s[4] + s[6]);
+       out[7] = SCALE8_STAGE2( s[0] + s[1] - s[2] + s[3]);
+}
+
+static inline void sbc_analyze_eight(struct sbc_encoder_state *state,
+                                       struct sbc_frame *frame, int ch,
+                                       int blk)
+{
+       int32_t *x = &state->X[ch][state->position[ch]];
+       int16_t *pcm = &frame->pcm_sample[ch][blk * 8];
+
+       /* Input 8 Audio Samples */
+       x[80] = x[0] = pcm[7];
+       x[81] = x[1] = pcm[6];
+       x[82] = x[2] = pcm[5];
+       x[83] = x[3] = pcm[4];
+       x[84] = x[4] = pcm[3];
+       x[85] = x[5] = pcm[2];
+       x[86] = x[6] = pcm[1];
+       x[87] = x[7] = pcm[0];
+
+       _sbc_analyze_eight(x, frame->sb_sample_f[blk][ch]);
+
+       state->position[ch] -= 8;
+       if (state->position[ch] < 0)
+               state->position[ch] = 72;
+}
+
+static int sbc_analyze_audio(struct sbc_encoder_state *state,
+                               struct sbc_frame *frame)
+{
+       int ch, blk;
+
+       switch (frame->subbands) {
+       case 4:
+               for (ch = 0; ch < frame->channels; ch++)
+                       for (blk = 0; blk < frame->blocks; blk++)
+                               sbc_analyze_four(state, frame, ch, blk);
+               return frame->blocks * 4;
+
+       case 8:
+               for (ch = 0; ch < frame->channels; ch++)
+                       for (blk = 0; blk < frame->blocks; blk++)
+                               sbc_analyze_eight(state, frame, ch, blk);
+               return frame->blocks * 8;
+
+       default:
+               return -EIO;
+       }
+}
+
+/*
+ * Packs the SBC frame from frame into the memory at data. At most len
+ * bytes will be used, should more memory be needed an appropriate
+ * error code will be returned. Returns the length of the packed frame
+ * on success or a negative value on error.
+ *
+ * The error codes are:
+ * -1 Not enough memory reserved
+ * -2 Unsupported sampling rate
+ * -3 Unsupported number of blocks
+ * -4 Unsupported number of subbands
+ * -5 Bitpool value out of bounds
+ * -99 not implemented
+ */
+
+static int sbc_pack_frame(uint8_t *data, struct sbc_frame *frame, size_t len)
+{
+       int produced;
+       /* Will copy the header parts for CRC-8 calculation here */
+       uint8_t crc_header[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+       int crc_pos = 0;
+
+       uint16_t audio_sample;
+
+       int ch, sb, blk, bit;   /* channel, subband, block and bit counters */
+       int bits[2][8];         /* bits distribution */
+       int levels[2][8];       /* levels are derived from that */
+
+       u_int32_t scalefactor[2][8];    /* derived from frame->scale_factor */
+
+       data[0] = SBC_SYNCWORD;
+
+       data[1] = (frame->frequency & 0x03) << 6;
+
+       data[1] |= (frame->block_mode & 0x03) << 4;
+
+       data[1] |= (frame->mode & 0x03) << 2;
+
+       data[1] |= (frame->allocation & 0x01) << 1;
+
+       switch (frame->subbands) {
+       case 4:
+               /* Nothing to do */
+               break;
+       case 8:
+               data[1] |= 0x01;
+               break;
+       default:
+               return -4;
+               break;
+       }
+
+       data[2] = frame->bitpool;
+
+       if ((frame->mode == MONO || frame->mode == DUAL_CHANNEL) &&
+                       frame->bitpool > frame->subbands << 4)
+               return -5;
+
+       if ((frame->mode == STEREO || frame->mode == JOINT_STEREO) &&
+                       frame->bitpool > frame->subbands << 5)
+               return -5;
+
+       /* Can't fill in crc yet */
+
+       produced = 32;
+
+       crc_header[0] = data[1];
+       crc_header[1] = data[2];
+       crc_pos = 16;
+
+       for (ch = 0; ch < frame->channels; ch++) {
+               for (sb = 0; sb < frame->subbands; sb++) {
+                       frame->scale_factor[ch][sb] = 0;
+                       scalefactor[ch][sb] = 2;
+                       for (blk = 0; blk < frame->blocks; blk++) {
+                               while (scalefactor[ch][sb] < fabs(frame->sb_sample_f[blk][ch][sb])) {
+                                       frame->scale_factor[ch][sb]++;
+                                       scalefactor[ch][sb] *= 2;
+                               }
+                       }
+               }
+       }
+
+       if (frame->mode == JOINT_STEREO) {
+               /* like frame->sb_sample but joint stereo */
+               int32_t sb_sample_j[16][2];
+               /* scalefactor and scale_factor in joint case */
+               u_int32_t scalefactor_j[2];
+               uint8_t scale_factor_j[2];
+
+               frame->joint = 0;
+
+               for (sb = 0; sb < frame->subbands - 1; sb++) {
+                       scale_factor_j[0] = 0;
+                       scalefactor_j[0] = 2;
+                       scale_factor_j[1] = 0;
+                       scalefactor_j[1] = 2;
+
+                       for (blk = 0; blk < frame->blocks; blk++) {
+                               /* Calculate joint stereo signal */
+                               sb_sample_j[blk][0] =
+                                       (frame->sb_sample_f[blk][0][sb] +
+                                               frame->sb_sample_f[blk][1][sb]) >> 1;
+                               sb_sample_j[blk][1] =
+                                       (frame->sb_sample_f[blk][0][sb] -
+                                               frame->sb_sample_f[blk][1][sb]) >> 1;
+
+                               /* calculate scale_factor_j and scalefactor_j for joint case */
+                               while (scalefactor_j[0] < fabs(sb_sample_j[blk][0])) {
+                                       scale_factor_j[0]++;
+                                       scalefactor_j[0] *= 2;
+                               }
+                               while (scalefactor_j[1] < fabs(sb_sample_j[blk][1])) {
+                                       scale_factor_j[1]++;
+                                       scalefactor_j[1] *= 2;
+                               }
+                       }
+
+                       /* decide whether to join this subband */
+                       if ((scalefactor[0][sb] + scalefactor[1][sb]) >
+                                       (scalefactor_j[0] + scalefactor_j[1]) ) {
+                               /* use joint stereo for this subband */
+                               frame->joint |= 1 << sb;
+                               frame->scale_factor[0][sb] = scale_factor_j[0];
+                               frame->scale_factor[1][sb] = scale_factor_j[1];
+                               scalefactor[0][sb] = scalefactor_j[0];
+                               scalefactor[1][sb] = scalefactor_j[1];
+                               for (blk = 0; blk < frame->blocks; blk++) {
+                                       frame->sb_sample_f[blk][0][sb] =
+                                                       sb_sample_j[blk][0];
+                                       frame->sb_sample_f[blk][1][sb] =
+                                                       sb_sample_j[blk][1];
+                               }
+                       }
+               }
+
+               data[4] = 0;
+               for (sb = 0; sb < frame->subbands - 1; sb++)
+                       data[4] |= ((frame->joint >> sb) & 0x01) << (frame->subbands - 1 - sb);
+
+               crc_header[crc_pos >> 3] = data[4];
+
+               produced += frame->subbands;
+               crc_pos += frame->subbands;
+       }
+
+       for (ch = 0; ch < frame->channels; ch++) {
+               for (sb = 0; sb < frame->subbands; sb++) {
+                       data[produced >> 3] <<= 4;
+                       crc_header[crc_pos >> 3] <<= 4;
+                       data[produced >> 3] |= frame->scale_factor[ch][sb] & 0x0F;
+                       crc_header[crc_pos >> 3] |= frame->scale_factor[ch][sb] & 0x0F;
+
+                       produced += 4;
+                       crc_pos += 4;
+               }
+       }
+
+       /* align the last crc byte */
+       if (crc_pos % 8)
+               crc_header[crc_pos >> 3] <<= 8 - (crc_pos % 8);
+
+       data[3] = sbc_crc8(crc_header, crc_pos);
+
+       sbc_calculate_bits(frame, bits);
+
+       for (ch = 0; ch < frame->channels; ch++) {
+               for (sb = 0; sb < frame->subbands; sb++)
+                       levels[ch][sb] = (1 << bits[ch][sb]) - 1;
+       }
+
+       for (blk = 0; blk < frame->blocks; blk++) {
+               for (ch = 0; ch < frame->channels; ch++) {
+                       for (sb = 0; sb < frame->subbands; sb++) {
+                               if (levels[ch][sb] > 0) {
+                                       audio_sample =
+                                               (uint16_t) ((((frame->sb_sample_f[blk][ch][sb]*levels[ch][sb]) >>
+                                                                       (frame->scale_factor[ch][sb] + 1)) +
+                                                               levels[ch][sb]) >> 1);
+                                       audio_sample <<= 16 - bits[ch][sb];
+                                       for (bit = 0; bit < bits[ch][sb]; bit++) {
+                                               data[produced >> 3] <<= 1;
+                                               if (audio_sample & 0x8000)
+                                                       data[produced >> 3] |= 0x1;
+                                               audio_sample <<= 1;
+                                               produced++;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /* align the last byte */
+       if (produced % 8) {
+               data[produced >> 3] <<= 8 - (produced % 8);
+       }
+
+       return (produced + 7) >> 3;
+}
+
+struct sbc_priv {
+       int init;
+       struct sbc_frame frame;
+       struct sbc_decoder_state dec_state;
+       struct sbc_encoder_state enc_state;
+};
+
+static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
+{
+       sbc->frequency = SBC_FREQ_44100;
+       sbc->mode = SBC_MODE_STEREO;
+       sbc->subbands = SBC_SB_8;
+       sbc->blocks = SBC_BLK_16;
+       sbc->bitpool = 32;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+       sbc->endian = SBC_LE;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+       sbc->endian = SBC_BE;
+#else
+#error "Unknown byte order"
+#endif
+}
+
+int sbc_init(sbc_t *sbc, unsigned long flags)
+{
+       if (!sbc)
+               return -EIO;
+
+       memset(sbc, 0, sizeof(sbc_t));
+
+       sbc->priv = malloc(sizeof(struct sbc_priv));
+       if (!sbc->priv)
+               return -ENOMEM;
+
+       memset(sbc->priv, 0, sizeof(struct sbc_priv));
+
+       sbc_set_defaults(sbc, flags);
+
+       return 0;
+}
+
+int sbc_parse(sbc_t *sbc, void *input, int input_len)
+{
+       return sbc_decode(sbc, input, input_len, NULL, 0, NULL);
+}
+
+int sbc_decode(sbc_t *sbc, void *input, int input_len, void *output,
+               int output_len, int *written)
+{
+       struct sbc_priv *priv;
+       char *ptr;
+       int i, ch, framelen, samples;
+
+       if (!sbc && !input)
+               return -EIO;
+
+       priv = sbc->priv;
+
+       framelen = sbc_unpack_frame(input, &priv->frame, input_len);
+
+       if (!priv->init) {
+               sbc_decoder_init(&priv->dec_state, &priv->frame);
+               priv->init = 1;
+
+               sbc->frequency = priv->frame.frequency;
+               sbc->mode = priv->frame.mode;
+               sbc->subbands = priv->frame.subband_mode;
+               sbc->blocks = priv->frame.block_mode;
+               sbc->allocation = priv->frame.allocation;
+               sbc->bitpool = priv->frame.bitpool;
+
+               priv->frame.codesize = sbc_get_codesize(sbc);
+               priv->frame.length = sbc_get_frame_length(sbc);
+       }
+
+       if (!output)
+               return framelen;
+
+       if (written)
+               *written = 0;
+
+       samples = sbc_synthesize_audio(&priv->dec_state, &priv->frame);
+
+       ptr = output;
+
+       if (output_len < samples * priv->frame.channels * 2)
+               samples = output_len / (priv->frame.channels * 2);
+
+       for (i = 0; i < samples; i++) {
+               for (ch = 0; ch < priv->frame.channels; ch++) {
+                       int16_t s;
+                       s = priv->frame.pcm_sample[ch][i];
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+                       if (sbc->endian == SBC_BE) {
+#elif __BYTE_ORDER == __BIG_ENDIAN
+                       if (sbc->endian == SBC_LE) {
+#else
+#error "Unknown byte order"
+#endif
+                               *ptr++ = (s & 0xff00) >> 8;
+                               *ptr++ = (s & 0x00ff);
+                       } else {
+                               *ptr++ = (s & 0x00ff);
+                               *ptr++ = (s & 0xff00) >> 8;
+                       }
+               }
+       }
+
+       if (written)
+               *written = samples * priv->frame.channels * 2;
+
+       return framelen;
+}
+
+int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output,
+               int output_len, int *written)
+{
+       struct sbc_priv *priv;
+       char *ptr;
+       int i, ch, framelen, samples;
+
+       if (!sbc && !input)
+               return -EIO;
+
+       priv = sbc->priv;
+
+       if (written)
+               *written = 0;
+
+       if (!priv->init) {
+               priv->frame.frequency = sbc->frequency;
+               priv->frame.mode = sbc->mode;
+               priv->frame.channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
+               priv->frame.allocation = sbc->allocation;
+               priv->frame.subband_mode = sbc->subbands;
+               priv->frame.subbands = sbc->subbands ? 8 : 4;
+               priv->frame.block_mode = sbc->blocks;
+               priv->frame.blocks = 4 + (sbc->blocks * 4);
+               priv->frame.bitpool = sbc->bitpool;
+               priv->frame.codesize = sbc_get_codesize(sbc);
+               priv->frame.length = sbc_get_frame_length(sbc);
+
+               sbc_encoder_init(&priv->enc_state, &priv->frame);
+               priv->init = 1;
+       }
+
+       /* input must be large enough to encode a complete frame */
+       if (input_len < priv->frame.codesize)
+               return 0;
+
+       /* output must be large enough to receive the encoded frame */
+       if (!output || output_len < priv->frame.length)
+               return -ENOSPC;
+
+       ptr = input;
+
+       for (i = 0; i < priv->frame.subbands * priv->frame.blocks; i++) {
+               for (ch = 0; ch < priv->frame.channels; ch++) {
+                       int16_t s;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+                       if (sbc->endian == SBC_BE)
+#elif __BYTE_ORDER == __BIG_ENDIAN
+                       if (sbc->endian == SBC_LE)
+#else
+#error "Unknown byte order"
+#endif
+                               s = (ptr[0] & 0xff) << 8 | (ptr[1] & 0xff);
+                       else
+                               s = (ptr[0] & 0xff) | (ptr[1] & 0xff) << 8;
+                       ptr += 2;
+                       priv->frame.pcm_sample[ch][i] = s;
+               }
+       }
+
+       samples = sbc_analyze_audio(&priv->enc_state, &priv->frame);
+
+       framelen = sbc_pack_frame(output, &priv->frame, output_len);
+
+       if (written)
+               *written = framelen;
+
+       return samples * priv->frame.channels * 2;
+}
+
+void sbc_finish(sbc_t *sbc)
+{
+       if (!sbc)
+               return;
+
+       if (sbc->priv)
+               free(sbc->priv);
+
+       memset(sbc, 0, sizeof(sbc_t));
+}
+
+int sbc_get_frame_length(sbc_t *sbc)
+{
+       int ret;
+       uint8_t subbands, channels, blocks, joint;
+       struct sbc_priv *priv;
+
+       priv = sbc->priv;
+       if (!priv->init) {
+               subbands = sbc->subbands ? 8 : 4;
+               blocks = 4 + (sbc->blocks * 4);
+               channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
+               joint = sbc->mode == SBC_MODE_JOINT_STEREO ? 1 : 0;
+       } else {
+               subbands = priv->frame.subbands;
+               blocks = priv->frame.blocks;
+               channels = priv->frame.channels;
+               joint = priv->frame.joint;
+       }
+
+       ret = 4 + (4 * subbands * channels) / 8;
+
+       /* This term is not always evenly divide so we round it up */
+       if (channels == 1)
+               ret += ((blocks * channels * sbc->bitpool) + 7) / 8;
+       else
+               ret += (((joint ? subbands : 0) + blocks * sbc->bitpool) + 7)
+                       / 8;
+
+       return ret;
+}
+
+int sbc_get_frame_duration(sbc_t *sbc)
+{
+       uint8_t subbands, blocks;
+       uint16_t frequency;
+       struct sbc_priv *priv;
+
+       priv = sbc->priv;
+       if (!priv->init) {
+               subbands = sbc->subbands ? 8 : 4;
+               blocks = 4 + (sbc->blocks * 4);
+       } else {
+               subbands = priv->frame.subbands;
+               blocks = priv->frame.blocks;
+       }
+
+       switch (sbc->frequency) {
+       case SBC_FREQ_16000:
+               frequency = 16000;
+               break;
+
+       case SBC_FREQ_32000:
+               frequency = 32000;
+               break;
+
+       case SBC_FREQ_44100:
+               frequency = 44100;
+               break;
+
+       case SBC_FREQ_48000:
+               frequency = 48000;
+               break;
+       default:
+               return 0;
+       }
+
+       return (1000000 * blocks * subbands) / frequency;
+}
+
+int sbc_get_codesize(sbc_t *sbc)
+{
+       uint8_t subbands, channels, blocks;
+       struct sbc_priv *priv;
+
+       priv = sbc->priv;
+       if (!priv->init) {
+               subbands = sbc->subbands ? 8 : 4;
+               blocks = 4 + (sbc->blocks * 4);
+               channels = sbc->mode == SBC_MODE_MONO ? 1 : 2;
+       } else {
+               subbands = priv->frame.subbands;
+               blocks = priv->frame.blocks;
+               channels = priv->frame.channels;
+       }
+
+       return subbands * blocks * channels * 2;
+}
+
+int sbc_reinit(sbc_t *sbc, unsigned long flags)
+{
+       struct sbc_priv *priv;
+
+       if (!sbc || !sbc->priv)
+               return -EIO;
+
+       priv = sbc->priv;
+
+       if (priv->init == 1)
+               memset(sbc->priv, 0, sizeof(struct sbc_priv));
+
+       sbc_set_defaults(sbc, flags);
+
+       return 0;
+}
diff --git a/src/modules/bluetooth/sbc.h b/src/modules/bluetooth/sbc.h
new file mode 100644 (file)
index 0000000..ab47e32
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *
+ *  Bluetooth low-complexity, subband codec (SBC) library
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
+ *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifndef __SBC_H
+#define __SBC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+/* sampling frequency */
+#define SBC_FREQ_16000         0x00
+#define SBC_FREQ_32000         0x01
+#define SBC_FREQ_44100         0x02
+#define SBC_FREQ_48000         0x03
+
+/* blocks */
+#define SBC_BLK_4              0x00
+#define SBC_BLK_8              0x01
+#define SBC_BLK_12             0x02
+#define SBC_BLK_16             0x03
+
+/* channel mode */
+#define SBC_MODE_MONO          0x00
+#define SBC_MODE_DUAL_CHANNEL  0x01
+#define SBC_MODE_STEREO                0x02
+#define SBC_MODE_JOINT_STEREO  0x03
+
+/* allocation method */
+#define SBC_AM_LOUDNESS                0x00
+#define SBC_AM_SNR             0x01
+
+/* subbands */
+#define SBC_SB_4               0x00
+#define SBC_SB_8               0x01
+
+/* Data endianess */
+#define SBC_LE                 0x00
+#define SBC_BE                 0x01
+
+struct sbc_struct {
+       unsigned long flags;
+
+       uint8_t frequency;
+       uint8_t blocks;
+       uint8_t subbands;
+       uint8_t mode;
+       uint8_t allocation;
+       uint8_t bitpool;
+       uint8_t endian;
+
+       void *priv;
+};
+
+typedef struct sbc_struct sbc_t;
+
+int sbc_init(sbc_t *sbc, unsigned long flags);
+int sbc_reinit(sbc_t *sbc, unsigned long flags);
+int sbc_parse(sbc_t *sbc, void *input, int input_len);
+int sbc_decode(sbc_t *sbc, void *input, int input_len, void *output,
+               int output_len, int *len);
+int sbc_encode(sbc_t *sbc, void *input, int input_len, void *output,
+               int output_len, int *written);
+int sbc_get_frame_length(sbc_t *sbc);
+int sbc_get_frame_duration(sbc_t *sbc);
+int sbc_get_codesize(sbc_t *sbc);
+void sbc_finish(sbc_t *sbc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SBC_H */
diff --git a/src/modules/bluetooth/sbc_math.h b/src/modules/bluetooth/sbc_math.h
new file mode 100644 (file)
index 0000000..b3d87a6
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ *
+ *  Bluetooth low-complexity, subband codec (SBC) library
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
+ *  Copyright (C) 2005-2008  Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#define fabs(x) ((x) < 0 ? -(x) : (x))
+/* C does not provide an explicit arithmetic shift right but this will
+   always be correct and every compiler *should* generate optimal code */
+#define ASR(val, bits) ((-2 >> 1 == -1) ? \
+                ((int32_t)(val)) >> (bits) : ((int32_t) (val)) / (1 << (bits)))
+
+#define SCALE_PROTO4_TBL       15
+#define SCALE_ANA4_TBL         17
+#define SCALE_PROTO8_TBL       16
+#define SCALE_ANA8_TBL         17
+#define SCALE_SPROTO4_TBL      12
+#define SCALE_SPROTO8_TBL      14
+#define SCALE_NPROTO4_TBL      11
+#define SCALE_NPROTO8_TBL      11
+#define SCALE4_STAGE1_BITS     15
+#define SCALE4_STAGE2_BITS     16
+#define SCALE4_STAGED1_BITS    15
+#define SCALE4_STAGED2_BITS    16
+#define SCALE8_STAGE1_BITS     15
+#define SCALE8_STAGE2_BITS     15
+#define SCALE8_STAGED1_BITS    15
+#define SCALE8_STAGED2_BITS    16
+
+typedef int32_t sbc_fixed_t;
+
+#define SCALE4_STAGE1(src)  ASR(src, SCALE4_STAGE1_BITS)
+#define SCALE4_STAGE2(src)  ASR(src, SCALE4_STAGE2_BITS)
+#define SCALE4_STAGED1(src) ASR(src, SCALE4_STAGED1_BITS)
+#define SCALE4_STAGED2(src) ASR(src, SCALE4_STAGED2_BITS)
+#define SCALE8_STAGE1(src)  ASR(src, SCALE8_STAGE1_BITS)
+#define SCALE8_STAGE2(src)  ASR(src, SCALE8_STAGE2_BITS)
+#define SCALE8_STAGED1(src) ASR(src, SCALE8_STAGED1_BITS)
+#define SCALE8_STAGED2(src) ASR(src, SCALE8_STAGED2_BITS)
+
+#define SBC_FIXED_0(val) { val = 0; }
+#define MUL(a, b)        ((a) * (b))
+#ifdef __arm__
+#define MULA(a, b, res) ({                             \
+               int tmp = res;                  \
+               __asm__(                                \
+                       "mla %0, %2, %3, %0"            \
+                       : "=&r" (tmp)                   \
+                       : "0" (tmp), "r" (a), "r" (b)); \
+               tmp; })
+#else
+#define MULA(a, b, res)  ((a) * (b) + (res))
+#endif
diff --git a/src/modules/bluetooth/sbc_tables.h b/src/modules/bluetooth/sbc_tables.h
new file mode 100644 (file)
index 0000000..7ac4e68
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ *
+ *  Bluetooth low-complexity, subband codec (SBC) library
+ *
+ *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2004-2005  Henryk Ploetz <henryk@ploetzli.ch>
+ *  Copyright (C) 2005-2006  Brad Midgley <bmidgley@xmission.com>
+ *
+ *
+ *  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 library 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+/* A2DP specification: Appendix B, page 69 */
+static const int sbc_offset4[4][4] = {
+       { -1, 0, 0, 0 },
+       { -2, 0, 0, 1 },
+       { -2, 0, 0, 1 },
+       { -2, 0, 0, 1 }
+};
+
+/* A2DP specification: Appendix B, page 69 */
+static const int sbc_offset8[4][8] = {
+       { -2, 0, 0, 0, 0, 0, 0, 1 },
+       { -3, 0, 0, 0, 0, 0, 1, 2 },
+       { -4, 0, 0, 0, 0, 0, 1, 2 },
+       { -4, 0, 0, 0, 0, 0, 1, 2 }
+};
+
+#define SP4(val) ASR(val, SCALE_PROTO4_TBL)
+#define SA4(val) ASR(val, SCALE_ANA4_TBL)
+#define SP8(val) ASR(val, SCALE_PROTO8_TBL)
+#define SA8(val) ASR(val, SCALE_ANA8_TBL)
+#define SS4(val) ASR(val, SCALE_SPROTO4_TBL)
+#define SS8(val) ASR(val, SCALE_SPROTO8_TBL)
+#define SN4(val) ASR(val, SCALE_NPROTO4_TBL)
+#define SN8(val) ASR(val, SCALE_NPROTO8_TBL)
+
+static const int32_t _sbc_proto_4[20] = {
+       SP4(0x02cb3e8c), SP4(0x22b63dc0), SP4(0x002329cc), SP4(0x053b7548),
+       SP4(0x31eab940), SP4(0xec1f5e60), SP4(0xff3773a8), SP4(0x0061c5a7),
+       SP4(0x07646680), SP4(0x3f239480), SP4(0xf89f23a8), SP4(0x007a4737),
+       SP4(0x00b32807), SP4(0x083ddc80), SP4(0x4825e480), SP4(0x0191e578),
+       SP4(0x00ff11ca), SP4(0x00fb7991), SP4(0x069fdc58), SP4(0x4b584000)
+};
+
+static const int32_t _anamatrix4[4] = {
+       SA4(0x2d413cc0), SA4(0x3b20d780), SA4(0x40000000), SA4(0x187de2a0)
+};
+
+static const int32_t _sbc_proto_8[40] = {
+       SP8(0x02e5cd20), SP8(0x22d0c200), SP8(0x006bfe27), SP8(0x07808930),
+       SP8(0x3f1c8800), SP8(0xf8810d70), SP8(0x002cfdc6), SP8(0x055acf28),
+       SP8(0x31f566c0), SP8(0xebfe57e0), SP8(0xff27c437), SP8(0x001485cc),
+       SP8(0x041c6e58), SP8(0x2a7cfa80), SP8(0xe4c4a240), SP8(0xfe359e4c),
+       SP8(0x0048b1f8), SP8(0x0686ce30), SP8(0x38eec5c0), SP8(0xf2a1b9f0),
+       SP8(0xffe8904a), SP8(0x0095698a), SP8(0x0824a480), SP8(0x443b3c00),
+       SP8(0xfd7badc8), SP8(0x00d3e2d9), SP8(0x00c183d2), SP8(0x084e1950),
+       SP8(0x4810d800), SP8(0x017f43fe), SP8(0x01056dd8), SP8(0x00e9cb9f),
+       SP8(0x07d7d090), SP8(0x4a708980), SP8(0x0488fae8), SP8(0x0113bd20),
+       SP8(0x0107b1a8), SP8(0x069fb3c0), SP8(0x4b3db200), SP8(0x00763f48)
+};
+
+static const int32_t sbc_proto_4_40m0[] = {
+       SS4(0x00000000), SS4(0xffa6982f), SS4(0xfba93848), SS4(0x0456c7b8),
+       SS4(0x005967d1), SS4(0xfffb9ac7), SS4(0xff589157), SS4(0xf9c2a8d8),
+       SS4(0x027c1434), SS4(0x0019118b), SS4(0xfff3c74c), SS4(0xff137330),
+       SS4(0xf81b8d70), SS4(0x00ec1b8b), SS4(0xfff0b71a), SS4(0xffe99b00),
+       SS4(0xfef84470), SS4(0xf6fb4370), SS4(0xffcdc351), SS4(0xffe01dc7)
+};
+
+static const int32_t sbc_proto_4_40m1[] = {
+       SS4(0xffe090ce), SS4(0xff2c0475), SS4(0xf694f800), SS4(0xff2c0475),
+       SS4(0xffe090ce), SS4(0xffe01dc7), SS4(0xffcdc351), SS4(0xf6fb4370),
+       SS4(0xfef84470), SS4(0xffe99b00), SS4(0xfff0b71a), SS4(0x00ec1b8b),
+       SS4(0xf81b8d70), SS4(0xff137330), SS4(0xfff3c74c), SS4(0x0019118b),
+       SS4(0x027c1434), SS4(0xf9c2a8d8), SS4(0xff589157), SS4(0xfffb9ac7)
+};
+
+static const int32_t sbc_proto_8_80m0[] = {
+       SS8(0x00000000), SS8(0xfe8d1970), SS8(0xee979f00), SS8(0x11686100),
+       SS8(0x0172e690), SS8(0xfff5bd1a), SS8(0xfdf1c8d4), SS8(0xeac182c0),
+       SS8(0x0d9daee0), SS8(0x00e530da), SS8(0xffe9811d), SS8(0xfd52986c),
+       SS8(0xe7054ca0), SS8(0x0a00d410), SS8(0x006c1de4), SS8(0xffdba705),
+       SS8(0xfcbc98e8), SS8(0xe3889d20), SS8(0x06af2308), SS8(0x000bb7db),
+       SS8(0xffca00ed), SS8(0xfc3fbb68), SS8(0xe071bc00), SS8(0x03bf7948),
+       SS8(0xffc4e05c), SS8(0xffb54b3b), SS8(0xfbedadc0), SS8(0xdde26200),
+       SS8(0x0142291c), SS8(0xff960e94), SS8(0xff9f3e17), SS8(0xfbd8f358),
+       SS8(0xdbf79400), SS8(0xff405e01), SS8(0xff7d4914), SS8(0xff8b1a31),
+       SS8(0xfc1417b8), SS8(0xdac7bb40), SS8(0xfdbb828c), SS8(0xff762170)
+};
+
+static const int32_t sbc_proto_8_80m1[] = {
+       SS8(0xff7c272c), SS8(0xfcb02620), SS8(0xda612700), SS8(0xfcb02620),
+       SS8(0xff7c272c), SS8(0xff762170), SS8(0xfdbb828c), SS8(0xdac7bb40),
+       SS8(0xfc1417b8), SS8(0xff8b1a31), SS8(0xff7d4914), SS8(0xff405e01),
+       SS8(0xdbf79400), SS8(0xfbd8f358), SS8(0xff9f3e17), SS8(0xff960e94),
+       SS8(0x0142291c), SS8(0xdde26200), SS8(0xfbedadc0), SS8(0xffb54b3b),
+       SS8(0xffc4e05c), SS8(0x03bf7948), SS8(0xe071bc00), SS8(0xfc3fbb68),
+       SS8(0xffca00ed), SS8(0x000bb7db), SS8(0x06af2308), SS8(0xe3889d20),
+       SS8(0xfcbc98e8), SS8(0xffdba705), SS8(0x006c1de4), SS8(0x0a00d410),
+       SS8(0xe7054ca0), SS8(0xfd52986c), SS8(0xffe9811d), SS8(0x00e530da),
+       SS8(0x0d9daee0), SS8(0xeac182c0), SS8(0xfdf1c8d4), SS8(0xfff5bd1a)
+};
+
+static const int32_t _anamatrix8[8] = {
+       SA8(0x3b20d780), SA8(0x187de2a0), SA8(0x3ec52f80), SA8(0x3536cc40),
+       SA8(0x238e7680), SA8(0x0c7c5c20), SA8(0x2d413cc0), SA8(0x40000000)
+};
+
+static const int32_t synmatrix4[8][4] = {
+       { SN4(0x05a82798), SN4(0xfa57d868), SN4(0xfa57d868), SN4(0x05a82798) },
+       { SN4(0x030fbc54), SN4(0xf89be510), SN4(0x07641af0), SN4(0xfcf043ac) },
+       { SN4(0x00000000), SN4(0x00000000), SN4(0x00000000), SN4(0x00000000) },
+       { SN4(0xfcf043ac), SN4(0x07641af0), SN4(0xf89be510), SN4(0x030fbc54) },
+       { SN4(0xfa57d868), SN4(0x05a82798), SN4(0x05a82798), SN4(0xfa57d868) },
+       { SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) },
+       { SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000), SN4(0xf8000000) },
+       { SN4(0xf89be510), SN4(0xfcf043ac), SN4(0x030fbc54), SN4(0x07641af0) }
+};
+
+static const int32_t synmatrix8[16][8] = {
+       { SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798),
+         SN8(0x05a82798), SN8(0xfa57d868), SN8(0xfa57d868), SN8(0x05a82798) },
+       { SN8(0x0471ced0), SN8(0xf8275a10), SN8(0x018f8b84), SN8(0x06a6d988),
+         SN8(0xf9592678), SN8(0xfe70747c), SN8(0x07d8a5f0), SN8(0xfb8e3130) },
+       { SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac),
+         SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54) },
+       { SN8(0x018f8b84), SN8(0xfb8e3130), SN8(0x06a6d988), SN8(0xf8275a10),
+         SN8(0x07d8a5f0), SN8(0xf9592678), SN8(0x0471ced0), SN8(0xfe70747c) },
+       { SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000),
+         SN8(0x00000000), SN8(0x00000000), SN8(0x00000000), SN8(0x00000000) },
+       { SN8(0xfe70747c), SN8(0x0471ced0), SN8(0xf9592678), SN8(0x07d8a5f0),
+         SN8(0xf8275a10), SN8(0x06a6d988), SN8(0xfb8e3130), SN8(0x018f8b84) },
+       { SN8(0xfcf043ac), SN8(0x07641af0), SN8(0xf89be510), SN8(0x030fbc54),
+         SN8(0x030fbc54), SN8(0xf89be510), SN8(0x07641af0), SN8(0xfcf043ac) },
+       { SN8(0xfb8e3130), SN8(0x07d8a5f0), SN8(0xfe70747c), SN8(0xf9592678),
+         SN8(0x06a6d988), SN8(0x018f8b84), SN8(0xf8275a10), SN8(0x0471ced0) },
+       { SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868),
+         SN8(0xfa57d868), SN8(0x05a82798), SN8(0x05a82798), SN8(0xfa57d868) },
+       { SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
+         SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) },
+       { SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
+         SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
+       { SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
+         SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
+       { SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000),
+         SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000), SN8(0xf8000000) },
+       { SN8(0xf8275a10), SN8(0xf9592678), SN8(0xfb8e3130), SN8(0xfe70747c),
+         SN8(0x018f8b84), SN8(0x0471ced0), SN8(0x06a6d988), SN8(0x07d8a5f0) },
+       { SN8(0xf89be510), SN8(0xfcf043ac), SN8(0x030fbc54), SN8(0x07641af0),
+         SN8(0x07641af0), SN8(0x030fbc54), SN8(0xfcf043ac), SN8(0xf89be510) },
+       { SN8(0xf9592678), SN8(0x018f8b84), SN8(0x07d8a5f0), SN8(0x0471ced0),
+         SN8(0xfb8e3130), SN8(0xf8275a10), SN8(0xfe70747c), SN8(0x06a6d988) }
+};
deleted file mode 100644 (file)
index 316beb72d1ef7a228503fc1ef0550d4fa77e0dff..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# This is a dirty trick just to ease compilation with emacs
-#
-# This file is not intended to be distributed or anything
-#
-# So: don't touch it, even better ignore it!
-
-all:
-       $(MAKE) -C ../..
-
-clean:
-       $(MAKE) -C ../.. clean
-
-.PHONY: all clean
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..efe5a3361d1c12d8943d6e6bca7af217a4211781
--- /dev/null
@@ -0,0 +1 @@
+../../pulse/Makefile
\ No newline at end of file
index 6e8ab6eaf0e2efe3bb808b23247cc4fdcc102c11..845ede50bc781a787d9c9dcfc155d8e4e06b7b0f 100644 (file)
@@ -378,7 +378,16 @@ void pa__done(pa_module*m) {
 
     if (u->pid != (pid_t) -1) {
         kill(u->pid, SIGTERM);
-        waitpid(u->pid, NULL, 0);
+
+        for (;;) {
+            if (waitpid(u->pid, NULL, 0) >= 0)
+                break;
+
+            if (errno != EINTR) {
+                pa_log("waitpid() failed: %s", pa_cstrerror(errno));
+                break;
+            }
+        }
     }
 
     if (u->io_event)
@@ -387,7 +396,6 @@ void pa__done(pa_module*m) {
     if (u->fd >= 0)
         pa_close(u->fd);
 
-
     if (u->module_infos)
         pa_hashmap_free(u->module_infos, module_info_free, u);
 
index b8bef935f9bc34ac25c7eb4b8485ceb1ca902911..0e15da3c71734919c420b33886a92911b467c37d 100644 (file)
@@ -539,8 +539,8 @@ static int suspend(struct userdata *u) {
 
     pa_smoother_pause(u->smoother, pa_rtclock_usec());
 
-    /* Let's suspend */
-    snd_pcm_drain(u->pcm_handle);
+    /* Let's suspend -- we don't call snd_pcm_drain() here since that might
+     * take awfully long with our long buffer sizes today. */
     snd_pcm_close(u->pcm_handle);
     u->pcm_handle = NULL;
 
@@ -569,7 +569,7 @@ static int update_sw_params(struct userdata *u) {
         if ((latency = pa_sink_get_requested_latency_within_thread(u->sink)) != (pa_usec_t) -1) {
             size_t b;
 
-            pa_log_debug("latency set to %0.2f", (double) latency / PA_USEC_PER_MSEC);
+            pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
 
             b = pa_usec_to_bytes(latency, &u->sink->sample_spec);
 
@@ -755,6 +755,21 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     return 0;
 }
 
+static pa_volume_t from_alsa_volume(struct userdata *u, long alsa_vol) {
+
+    return (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) /
+                               (double) (u->hw_volume_max - u->hw_volume_min));
+}
+
+static long to_alsa_volume(struct userdata *u, pa_volume_t vol) {
+    long alsa_vol;
+
+    alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min))
+                            / PA_VOLUME_NORM) + u->hw_volume_min;
+
+    return PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
+}
+
 static int sink_get_volume_cb(pa_sink *s) {
     struct userdata *u = s->userdata;
     int err;
@@ -787,23 +802,31 @@ static int sink_get_volume_cb(pa_sink *s) {
                 if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
                     goto fail;
 
-                r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
+                r.values[i] = from_alsa_volume(u, alsa_vol);
             }
         }
 
     } else {
         long alsa_vol;
 
-        pa_assert(u->hw_dB_supported);
+        if (u->hw_dB_supported) {
 
-        if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
-            goto fail;
+            if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
 
 #ifdef HAVE_VALGRIND_MEMCHECK_H
-                VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
+            VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
 #endif
 
-        pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+            pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+
+        } else {
+
+            if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
+
+            pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
+        }
     }
 
     pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
@@ -861,10 +884,9 @@ static int sink_set_volume_cb(pa_sink *s) {
                     goto fail;
 
                 r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0);
-            } else {
 
-                alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
-                alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
+            } else {
+                alsa_vol = to_alsa_volume(u, vol);
 
                 if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
                     goto fail;
@@ -872,7 +894,7 @@ static int sink_set_volume_cb(pa_sink *s) {
                 if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
                     goto fail;
 
-                r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
+                r.values[i] = from_alsa_volume(u, alsa_vol);
             }
         }
 
@@ -880,20 +902,31 @@ static int sink_set_volume_cb(pa_sink *s) {
         pa_volume_t vol;
         long alsa_vol;
 
-        pa_assert(u->hw_dB_supported);
-
         vol = pa_cvolume_max(&s->volume);
 
-        alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
-        alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
+        if (u->hw_dB_supported) {
+            alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
+            alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
 
-        if ((err = snd_mixer_selem_set_playback_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
-            goto fail;
+            if ((err = snd_mixer_selem_set_playback_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
+                goto fail;
 
-        if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
-            goto fail;
+            if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
+
+            pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
 
-        pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+        } else {
+            alsa_vol = to_alsa_volume(u, vol);
+
+            if ((err = snd_mixer_selem_set_playback_volume_all(u->mixer_elem, alsa_vol)) < 0)
+                goto fail;
+
+            if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
+
+            pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
+        }
     }
 
     u->hardware_volume = r;
@@ -903,7 +936,7 @@ static int sink_set_volume_cb(pa_sink *s) {
 
         /* Match exactly what the user requested by software */
 
-        pa_alsa_volume_divide(&r, &s->volume);
+        pa_sw_cvolume_divide(&r, &s->volume, &r);
         pa_sink_set_soft_volume(s, &r);
 
         pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
@@ -1136,7 +1169,7 @@ static void thread_func(void *userdata) {
             pa_rtpoll_set_timer_disabled(u->rtpoll);
 
         /* Hmm, nothing to do. Let's sleep */
-        if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0)
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
 
         if (ret == 0)
@@ -1441,14 +1474,15 @@ int pa__init(pa_module*m) {
         pa_assert(u->mixer_elem);
 
         if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) {
-            pa_bool_t suitable = TRUE;
+            pa_bool_t suitable = FALSE;
 
-            if (snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0) {
+            if (snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0)
                 pa_log_info("Failed to get volume range. Falling back to software volume control.");
-                suitable = FALSE;
-            } else {
+            else if (u->hw_volume_min >= u->hw_volume_max)
+                pa_log_warn("Your kernel driver is broken: it reports a volume range from %li to %li which makes no sense.", u->hw_volume_min, u->hw_volume_max);
+            else {
                 pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max);
-                pa_assert(u->hw_volume_min < u->hw_volume_max);
+                suitable = TRUE;
             }
 
             if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
@@ -1459,9 +1493,12 @@ int pa__init(pa_module*m) {
                 VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
 #endif
 
-                pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
-                pa_assert(u->hw_dB_min < u->hw_dB_max);
-                u->hw_dB_supported = TRUE;
+                if (u->hw_dB_min >= u->hw_dB_max)
+                    pa_log_warn("Your kernel driver is broken: it reports a volume range from %0.2f dB to %0.2f dB which makes no sense.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
+                else {
+                    pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
+                    u->hw_dB_supported = TRUE;
+                }
             }
 
             if (suitable &&
index cb777672d6f2052297cff3dd0de42d0e13283df0..2827ecfef627a7d3aaaf0208ad3992447e1cd513 100644 (file)
@@ -211,9 +211,10 @@ static int try_recover(struct userdata *u, const char *call, int err) {
 
 static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
     size_t left_to_record;
+    size_t rec_space = u->hwbuf_size - (size_t) u->hwbuf_unused_frames*u->frame_size;
 
-    if ((size_t) n*u->frame_size < u->hwbuf_size)
-        left_to_record = u->hwbuf_size - ((size_t) n*u->frame_size);
+    if ((size_t) n*u->frame_size < rec_space)
+        left_to_record = rec_space - ((size_t) n*u->frame_size);
     else
         left_to_record = 0;
 
@@ -514,7 +515,7 @@ static int update_sw_params(struct userdata *u) {
         if ((latency = pa_source_get_requested_latency_within_thread(u->source)) != (pa_usec_t) -1) {
             size_t b;
 
-            pa_log_debug("latency set to %0.2f", (double) latency / PA_USEC_PER_MSEC);
+            pa_log_debug("latency set to %0.2fms", (double) latency / PA_USEC_PER_MSEC);
 
             b = pa_usec_to_bytes(latency, &u->source->sample_spec);
 
@@ -700,6 +701,21 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
     return 0;
 }
 
+static pa_volume_t from_alsa_volume(struct userdata *u, long alsa_vol) {
+
+    return (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) /
+                               (double) (u->hw_volume_max - u->hw_volume_min));
+}
+
+static long to_alsa_volume(struct userdata *u, pa_volume_t vol) {
+    long alsa_vol;
+
+    alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min))
+                            / PA_VOLUME_NORM) + u->hw_volume_min;
+
+    return PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
+}
+
 static int source_get_volume_cb(pa_source *s) {
     struct userdata *u = s->userdata;
     int err;
@@ -732,23 +748,31 @@ static int source_get_volume_cb(pa_source *s) {
                 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
                     goto fail;
 
-                r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
+                r.values[i] = from_alsa_volume(u, alsa_vol);
             }
         }
 
     } else {
         long alsa_vol;
 
-        pa_assert(u->hw_dB_supported);
+        if (u->hw_dB_supported) {
 
-        if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
-            goto fail;
+            if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
 
 #ifdef HAVE_VALGRIND_MEMCHECK_H
-        VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
+            VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
 #endif
 
-        pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+            pa_cvolume_set(&r, s->sample_spec.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+
+        } else {
+
+            if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
+
+            pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
+        }
     }
 
     pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
@@ -784,7 +808,7 @@ static int source_set_volume_cb(pa_source *s) {
     pa_assert(u);
     pa_assert(u->mixer_elem);
 
-        if (u->mixer_seperate_channels) {
+    if (u->mixer_seperate_channels) {
 
         r.channels = s->sample_spec.channels;
 
@@ -806,10 +830,9 @@ static int source_set_volume_cb(pa_source *s) {
                     goto fail;
 
                 r.values[i] = pa_sw_volume_from_dB((double) alsa_vol / 100.0);
-            } else {
 
-                alsa_vol = (long) round(((double) vol * (double) (u->hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
-                alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_volume_min, u->hw_volume_max);
+            } else {
+                alsa_vol = to_alsa_volume(u, vol);
 
                 if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
                     goto fail;
@@ -817,7 +840,7 @@ static int source_set_volume_cb(pa_source *s) {
                 if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
                     goto fail;
 
-                r.values[i] = (pa_volume_t) round(((double) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (double) (u->hw_volume_max - u->hw_volume_min));
+                r.values[i] = from_alsa_volume(u, alsa_vol);
             }
         }
 
@@ -825,20 +848,31 @@ static int source_set_volume_cb(pa_source *s) {
         pa_volume_t vol;
         long alsa_vol;
 
-        pa_assert(u->hw_dB_supported);
-
         vol = pa_cvolume_max(&s->volume);
 
-        alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
-        alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
+        if (u->hw_dB_supported) {
+            alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
+            alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
 
-        if ((err = snd_mixer_selem_set_capture_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
-            goto fail;
+            if ((err = snd_mixer_selem_set_capture_dB_all(u->mixer_elem, alsa_vol, 1)) < 0)
+                goto fail;
 
-        if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
-            goto fail;
+            if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
+
+            pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+
+        } else {
+            alsa_vol = to_alsa_volume(u, vol);
+
+            if ((err = snd_mixer_selem_set_capture_volume_all(u->mixer_elem, alsa_vol)) < 0)
+                goto fail;
+
+            if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+                goto fail;
 
-        pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) alsa_vol / 100.0));
+            pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
+        }
     }
 
     u->hardware_volume = r;
@@ -848,7 +882,7 @@ static int source_set_volume_cb(pa_source *s) {
 
         /* Match exactly what the user requested by software */
 
-        pa_alsa_volume_divide(&r, &s->volume);
+        pa_sw_cvolume_divide(&r, &s->volume, &r);
         pa_source_set_soft_volume(s, &r);
 
         pa_log_debug("Requested volume: %s", pa_cvolume_snprint(t, sizeof(t), &s->volume));
@@ -971,7 +1005,7 @@ static void thread_func(void *userdata) {
             pa_rtpoll_set_timer_disabled(u->rtpoll);
 
         /* Hmm, nothing to do. Let's sleep */
-        if ((ret = pa_rtpoll_run(u->rtpoll, 1)) < 0)
+        if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
             goto fail;
 
         if (ret == 0)
@@ -1262,14 +1296,15 @@ int pa__init(pa_module*m) {
         pa_assert(u->mixer_elem);
 
         if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
-            pa_bool_t suitable = TRUE;
+            pa_bool_t suitable = FALSE;
 
-            if (snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0) {
+            if (snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) < 0)
                 pa_log_info("Failed to get volume range. Falling back to software volume control.");
-                suitable = FALSE;
-            } else {
+            else if (u->hw_volume_min >= u->hw_volume_max)
+                pa_log_warn("Your kernel driver is broken: it reports a volume range from %li to %li which makes no sense.", u->hw_volume_min, u->hw_volume_max);
+            else {
                 pa_log_info("Volume ranges from %li to %li.", u->hw_volume_min, u->hw_volume_max);
-                pa_assert(u->hw_volume_min < u->hw_volume_max);
+                suitable = TRUE;
             }
 
             if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
@@ -1280,9 +1315,12 @@ int pa__init(pa_module*m) {
                 VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
 #endif
 
-                pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
-                pa_assert(u->hw_dB_min < u->hw_dB_max);
-                u->hw_dB_supported = TRUE;
+                if (u->hw_dB_min >= u->hw_dB_max)
+                    pa_log_warn("Your kernel driver is broken: it reports a volume range from %0.2f dB to %0.2f dB which makes no sense.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
+                else {
+                    pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", (double) u->hw_dB_min/100.0, (double) u->hw_dB_max/100.0);
+                    u->hw_dB_supported = TRUE;
+                }
             }
 
             if (suitable &&
@@ -1293,7 +1331,6 @@ int pa__init(pa_module*m) {
                 suitable = FALSE;
             }
 
-
             if (suitable) {
                 u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0;
 
index 9162960fe7a963ab86e1a3118eedfc4bd115a7b1..470c622e342e4cee25bd79f9030f04ede85e8b2c 100644 (file)
@@ -137,13 +137,13 @@ static void process_rewind(struct userdata *u, pa_usec_t now) {
     pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
 
     if (u->timestamp <= now)
-        return;
+        goto do_nothing;
 
     delay = u->timestamp - now;
     in_buffer = pa_usec_to_bytes(delay, &u->sink->sample_spec);
 
     if (in_buffer <= 0)
-        return;
+        goto do_nothing;
 
     if (rewind_nbytes > in_buffer)
         rewind_nbytes = in_buffer;
@@ -152,6 +152,11 @@ static void process_rewind(struct userdata *u, pa_usec_t now) {
     u->timestamp -= pa_bytes_to_usec(rewind_nbytes, &u->sink->sample_spec);
 
     pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes);
+    return;
+
+do_nothing:
+
+    pa_sink_process_rewind(u->sink, 0);
 }
 
 static void process_render(struct userdata *u, pa_usec_t now) {
index 0e98b1c3e5196ade4b4bfd0f90394bf79e64c3b4..aefd4020fe1500294d7708f777afa9754f9cc62d 100644 (file)
 #  include <pulsecore/esound.h>
 #  define TCPWRAP_SERVICE "esound"
 #  define IPV4_PORT ESD_DEFAULT_PORT
-#  define MODULE_ARGUMENTS_COMMON "sink", "source", "auth-anonymous", "cookie", "auth-cookie", "auth-cookie-enabled"
+#  define MODULE_ARGUMENTS_COMMON "sink", "source", "auth-anonymous", "cookie", "auth-cookie", "auth-cookie-enabled",
 
 #  ifdef USE_TCP_SOCKETS
 #    include "module-esound-protocol-tcp-symdef.h"
index bc7c023ca07f28c45d2feaafbaecf31b62d3a66a..6cc28ec52c0ccf5f04680621c96603ba0c3ffdc0 100644 (file)
@@ -337,7 +337,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
 int pa__init(pa_module*m) {
     pa_modargs *ma = NULL;
     struct userdata *u;
-    uint32_t timeout = 1;
+    uint32_t timeout = 5;
     uint32_t idx;
     pa_sink *sink;
     pa_source *source;
index de3c7274a10cdc716c21d05a4b1ec86e0130f5c9..4bbb11a5a7266a0794d2ebd10d8ea73d3f80ee49 100644 (file)
@@ -159,7 +159,7 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
     [PA_COMMAND_PLAYBACK_STREAM_SUSPENDED] = command_suspended,
     [PA_COMMAND_RECORD_STREAM_SUSPENDED] = command_suspended,
     [PA_COMMAND_PLAYBACK_STREAM_MOVED] = command_moved,
-    [PA_COMMAND_RECORD_STREAM_MOVED] = command_moved,
+    [PA_COMMAND_RECORD_STREAM_MOVED] = command_moved
 };
 
 struct userdata {
@@ -1494,6 +1494,13 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
 #endif
     }
 
+    if (u->version >= 14) {
+#ifdef TUNNEL_SINK
+        pa_tagstruct_put_boolean(reply, FALSE); /* volume_set */
+#endif
+        pa_tagstruct_put_boolean(reply, TRUE); /* early rquests */
+    }
+
     pa_pstream_send_tagstruct(u->pstream, reply);
     pa_pdispatch_register_reply(u->pdispatch, tag, DEFAULT_TIMEOUT, create_stream_callback, u, NULL);
 
deleted file mode 100644 (file)
index 316beb72d1ef7a228503fc1ef0550d4fa77e0dff..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# This is a dirty trick just to ease compilation with emacs
-#
-# This file is not intended to be distributed or anything
-#
-# So: don't touch it, even better ignore it!
-
-all:
-       $(MAKE) -C ../..
-
-clean:
-       $(MAKE) -C ../.. clean
-
-.PHONY: all clean
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..efe5a3361d1c12d8943d6e6bca7af217a4211781
--- /dev/null
@@ -0,0 +1 @@
+../../pulse/Makefile
\ No newline at end of file
index 01637892c1d81e2471f30d471790057edc78975c..e35773cce00c7984e475bc48c1a1fea5a695cf2f 100644 (file)
@@ -249,7 +249,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
         pa_memblockq_seek(s->memblockq, (int64_t) chunk.length, PA_SEEK_RELATIVE);
     }
 
-    pa_log("blocks in q: %u", pa_memblockq_get_nblocks(s->memblockq));
+/*     pa_log("blocks in q: %u", pa_memblockq_get_nblocks(s->memblockq)); */
 
     pa_memblock_unref(chunk.memblock);
 
index 373087515c0a12d04018155cb2db128a26dc1ddf..fd313bd3447fcf234e6ac7327d9cf608b4009196 100644 (file)
@@ -466,6 +466,13 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
     pa_assert(l > 0);
     pa_assert(map);
 
+    pa_init_i18n();
+
+    if (!pa_channel_map_valid(map)) {
+        pa_snprintf(s, l, _("(invalid)"));
+        return s;
+    }
+
     *(e = s) = 0;
 
     for (channel = 0; channel < map->channels && l > 1; channel++) {
@@ -562,5 +569,11 @@ int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *s
     pa_assert(map);
     pa_assert(ss);
 
+    if (!pa_channel_map_valid(map))
+        return 0;
+
+    if (!pa_sample_spec_valid(ss))
+        return 0;
+
     return map->channels == ss->channels;
 }
index d2dd6f8f917ed4f3f3fd583795a2de1e9b9bb633..d7d19d79e432d2583845edc0f10e37797e15038f 100644 (file)
@@ -175,7 +175,9 @@ typedef struct pa_channel_map {
     /**< Channel labels */
 } pa_channel_map;
 
-/** Initialize the specified channel map and return a pointer to it */
+/** Initialize the specified channel map and return a pointer to
+ * it. The channel map will have a defined state but
+ * pa_channel_map_valid() will fail for it. */
 pa_channel_map* pa_channel_map_init(pa_channel_map *m);
 
 /** Initialize the specified channel map for monoaural audio and return a pointer to it */
@@ -202,7 +204,11 @@ const char* pa_channel_position_to_string(pa_channel_position_t pos) PA_GCC_PURE
 /** Return a human readable text label for the specified channel position. \since 0.9.7 */
 const char* pa_channel_position_to_pretty_string(pa_channel_position_t pos);
 
-/** The maximum length of strings returned by pa_channel_map_snprint() */
+/** The maximum length of strings returned by
+ * pa_channel_map_snprint(). Please note that this value can change
+ * with any release without warning and without being considered API
+ * or ABI breakage. You should not use this definition anywhere where
+ * it might become part of an ABI. */
 #define PA_CHANNEL_MAP_SNPRINT_MAX 336
 
 /** Make a humand readable string from the specified channel map */
index 739ef1610aae0e8674a02d4092429fb54f070891..58d64642adfb5c3dc6945d4dfbe709b376cfaa13 100644 (file)
@@ -61,6 +61,7 @@ static const pa_client_conf default_conf = {
     .disable_shm = FALSE,
     .cookie_file = NULL,
     .cookie_valid = FALSE,
+    .shm_size = 0
 };
 
 pa_client_conf *pa_client_conf_new(void) {
@@ -99,6 +100,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
         { "autospawn",              pa_config_parse_bool,    NULL },
         { "cookie-file",            pa_config_parse_string,  NULL },
         { "disable-shm",            pa_config_parse_bool,    NULL },
+        { "shm-size-bytes",         pa_config_parse_size,    NULL },
         { NULL,                     NULL,                    NULL },
     };
 
@@ -110,6 +112,7 @@ int pa_client_conf_load(pa_client_conf *c, const char *filename) {
     table[5].data = &c->autospawn;
     table[6].data = &c->cookie_file;
     table[7].data = &c->disable_shm;
+    table[8].data = &c->shm_size;
 
     if (filename) {
 
index 699279aaba161a4e6efd62913a1c54571588a905..4eac467ea6518115d5206355612e022dbeb371c4 100644 (file)
@@ -31,6 +31,7 @@ typedef struct pa_client_conf {
     pa_bool_t autospawn, disable_shm;
     uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
     pa_bool_t cookie_valid; /* non-zero, when cookie is valid */
+    size_t shm_size;
 } pa_client_conf;
 
 /* Create a new configuration data object and reset it to defaults */
index 8339d6514aeb294e3992c126150ce5d448485391..579bcc2046fc16665df5130498bb4d43ac1ac4a9 100644 (file)
@@ -30,3 +30,4 @@
 ; cookie-file =
 
 ; disable-shm = no
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
index 154e5faf6e4b82297f0d722a9f554260e04e8807..3145d9c80ccdd18ca96c6da6c23faa03b8700bd2 100644 (file)
@@ -174,10 +174,10 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
     pa_client_conf_load(c->conf, NULL);
     pa_client_conf_env(c->conf);
 
-    if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm))) {
+    if (!(c->mempool = pa_mempool_new(!c->conf->disable_shm, c->conf->shm_size))) {
 
         if (!c->conf->disable_shm)
-            c->mempool = pa_mempool_new(FALSE);
+            c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
 
         if (!c->mempool) {
             context_free(c);
index 4e362fd86c53e59c7f568b212f1565931089e2ff..38091581b7409c43a07021b7ed799775c0f7cd00 100644 (file)
@@ -24,6 +24,8 @@
 #include <config.h>
 #endif
 
+#include <string.h>
+
 #include <pulse/context.h>
 #include <pulse/gccmacro.h>
 
index 93da2465f4301e27af4976e82737c3a048124a68..2950159554520c8702c27271a85534e888ca3990 100644 (file)
@@ -80,6 +80,16 @@ size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) {
     return (size_t) (((t * spec->rate) / PA_USEC_PER_SEC)) * pa_frame_size(spec);
 }
 
+pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec) {
+    pa_assert(spec);
+
+    spec->format = PA_SAMPLE_INVALID;
+    spec->rate = 0;
+    spec->channels = 0;
+
+    return spec;
+}
+
 int pa_sample_spec_valid(const pa_sample_spec *spec) {
     pa_assert(spec);
 
@@ -131,7 +141,7 @@ char *pa_sample_spec_snprint(char *s, size_t l, const pa_sample_spec *spec) {
     pa_init_i18n();
 
     if (!pa_sample_spec_valid(spec))
-        pa_snprintf(s, l, _("Invalid"));
+        pa_snprintf(s, l, _("(invalid)"));
     else
         pa_snprintf(s, l, "%s %uch %uHz", pa_sample_format_to_string(spec->format), spec->channels, spec->rate);
 
index 3f1b2fcf33ed5c7319346b03061db6319af7f5bf..3c7dd0e72579c4019749c6f0b2e1b6d9160d58cc 100644 (file)
@@ -232,6 +232,11 @@ pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) PA_GCC_P
  * return values. \since 0.9 */
 size_t pa_usec_to_bytes(pa_usec_t t, const pa_sample_spec *spec) PA_GCC_PURE;
 
+/** Initialize the specified sample spec and return a pointer to
+ * it. The sample spec will have a defined state but
+ * pa_sample_spec_valid() will fail for it. \since 0.9.13 */
+pa_sample_spec* pa_sample_spec_init(pa_sample_spec *spec);
+
 /** Return non-zero when the sample type specification is valid */
 int pa_sample_spec_valid(const pa_sample_spec *spec) PA_GCC_PURE;
 
@@ -244,7 +249,11 @@ const char *pa_sample_format_to_string(pa_sample_format_t f) PA_GCC_PURE;
 /** Parse a sample format text. Inverse of pa_sample_format_to_string() */
 pa_sample_format_t pa_parse_sample_format(const char *format) PA_GCC_PURE;
 
-/** Maximum required string length for pa_sample_spec_snprint() */
+/** Maximum required string length for
+ * pa_sample_spec_snprint(). Please note that this value can change
+ * with any release without warning and without being considered API
+ * or ABI breakage. You should not use this definition anywhere where
+ * it might become part of an ABI. */
 #define PA_SAMPLE_SPEC_SNPRINT_MAX 32
 
 /** Pretty print a sample type specification to a string */
index d0c7d67e52ba65aee4751ee780aa7dfd643aba94..00aa1cf971c8c8ebaff87efcd1dc5364ecb41be6 100644 (file)
@@ -86,7 +86,7 @@ pa_stream *pa_stream_new_with_proplist(
     pa_assert(PA_REFCNT_VALUE(c) >= 1);
 
     PA_CHECK_VALIDITY_RETURN_NULL(c, ss && pa_sample_spec_valid(ss), PA_ERR_INVALID);
-    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 12 || (ss->format != PA_SAMPLE_S32LE || ss->format != PA_SAMPLE_S32NE), PA_ERR_NOTSUPPORTED);
+    PA_CHECK_VALIDITY_RETURN_NULL(c, c->version >= 12 || (ss->format != PA_SAMPLE_S32LE && ss->format != PA_SAMPLE_S32BE), PA_ERR_NOTSUPPORTED);
     PA_CHECK_VALIDITY_RETURN_NULL(c, !map || (pa_channel_map_valid(map) && map->channels == ss->channels), PA_ERR_INVALID);
     PA_CHECK_VALIDITY_RETURN_NULL(c, name || (p && pa_proplist_contains(p, PA_PROP_MEDIA_NAME)), PA_ERR_INVALID);
 
@@ -557,7 +557,7 @@ void pa_command_stream_started(pa_pdispatch *pd, uint32_t command, uint32_t tag,
     request_auto_timing_update(s, TRUE);
 
     if (s->started_callback)
-        s->started_callback(s, s->suspended_userdata);
+        s->started_callback(s, s->started_userdata);
 
 finish:
     pa_context_unref(c);
@@ -1851,7 +1851,7 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe
     if (s->context->version >= 13) {
         pa_proplist *p = pa_proplist_new();
 
-        pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, name);
+        pa_proplist_sets(p, PA_PROP_MEDIA_NAME, name);
         o = pa_stream_proplist_update(s, PA_UPDATE_REPLACE, p, cb, userdata);
         pa_proplist_free(p);
     } else {
@@ -2010,7 +2010,6 @@ static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command,
 
         success = 0;
     } else {
-
         if (o->stream->direction == PA_STREAM_PLAYBACK) {
             if (pa_tagstruct_getu32(t, &o->stream->buffer_attr.maxlength) < 0 ||
                 pa_tagstruct_getu32(t, &o->stream->buffer_attr.tlength) < 0 ||
@@ -2027,6 +2026,20 @@ static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command,
             }
         }
 
+        if (o->stream->context->version >= 13) {
+            pa_usec_t usec;
+
+            if (pa_tagstruct_get_usec(t, &usec) < 0) {
+                pa_context_fail(o->context, PA_ERR_PROTOCOL);
+                goto finish;
+            }
+
+            if (o->stream->direction == PA_STREAM_RECORD)
+                o->stream->timing_info.configured_source_usec = usec;
+            else
+                o->stream->timing_info.configured_sink_usec = usec;
+        }
+
         if (!pa_tagstruct_eof(t)) {
             pa_context_fail(o->context, PA_ERR_PROTOCOL);
             goto finish;
index 15938cbc74ec7baa42fd67ffff3e324904913aab..99a85f4482cd14d81576b485a40e07c4247c469f 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <pulse/i18n.h>
 #include <pulsecore/core-util.h>
 #include <pulsecore/macro.h>
 
@@ -46,6 +47,19 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) {
     return 1;
 }
 
+pa_cvolume* pa_cvolume_init(pa_cvolume *a) {
+    unsigned c;
+
+    pa_assert(a);
+
+    a->channels = 0;
+
+    for (c = 0; c < PA_CHANNELS_MAX; c++)
+        a->values[c] = (pa_volume_t) -1;
+
+    return a;
+}
+
 pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
     int i;
 
@@ -87,7 +101,16 @@ pa_volume_t pa_cvolume_max(const pa_cvolume *a) {
 }
 
 pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
-    return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a)* pa_sw_volume_to_linear(b));
+    return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a) * pa_sw_volume_to_linear(b));
+}
+
+pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) {
+    double v = pa_sw_volume_to_linear(b);
+
+    if (v <= 0)
+        return 0;
+
+    return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a) / v);
 }
 
 #define USER_DECIBEL_RANGE 60
@@ -96,7 +119,7 @@ pa_volume_t pa_sw_volume_from_dB(double dB) {
     if (isinf(dB) < 0 || dB <= -USER_DECIBEL_RANGE)
         return PA_VOLUME_MUTED;
 
-    return (pa_volume_t) ((dB/USER_DECIBEL_RANGE+1)*PA_VOLUME_NORM);
+    return (pa_volume_t) lrint((dB/USER_DECIBEL_RANGE+1)*PA_VOLUME_NORM);
 }
 
 double pa_sw_volume_to_dB(pa_volume_t v) {
@@ -127,13 +150,20 @@ double pa_sw_volume_to_linear(pa_volume_t v) {
 
 char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) {
     unsigned channel;
-    int first = 1;
+    pa_bool_t first = TRUE;
     char *e;
 
     pa_assert(s);
     pa_assert(l > 0);
     pa_assert(c);
 
+    pa_init_i18n();
+
+    if (!pa_cvolume_valid(c)) {
+        pa_snprintf(s, l, _("(invalid)"));
+        return s;
+    }
+
     *(e = s) = 0;
 
     for (channel = 0; channel < c->channels && l > 1; channel++) {
@@ -143,7 +173,38 @@ char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c) {
                       (c->values[channel]*100)/PA_VOLUME_NORM);
 
         e = strchr(e, 0);
-        first = 0;
+        first = FALSE;
+    }
+
+    return s;
+}
+
+char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c) {
+    unsigned channel;
+    pa_bool_t first = TRUE;
+    char *e;
+
+    pa_assert(s);
+    pa_assert(l > 0);
+    pa_assert(c);
+
+    pa_init_i18n();
+
+    if (!pa_cvolume_valid(c)) {
+        pa_snprintf(s, l, _("(invalid)"));
+        return s;
+    }
+
+    *(e = s) = 0;
+
+    for (channel = 0; channel < c->channels && l > 1; channel++) {
+        l -= pa_snprintf(e, l, "%s%u: %0.2f dB",
+                      first ? "" : " ",
+                      channel,
+                      pa_sw_volume_to_dB(c->values[channel]));
+
+        e = strchr(e, 0);
+        first = FALSE;
     }
 
     return s;
@@ -168,12 +229,23 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
     pa_assert(a);
     pa_assert(b);
 
-    for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++) {
+    for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
+        dest->values[i] = pa_sw_volume_multiply(a->values[i], b->values[i]);
 
-        dest->values[i] = pa_sw_volume_multiply(
-            i < a->channels ? a->values[i] : PA_VOLUME_NORM,
-            i < b->channels ? b->values[i] : PA_VOLUME_NORM);
-    }
+    dest->channels = (uint8_t) i;
+
+    return dest;
+}
+
+pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b) {
+    unsigned i;
+
+    pa_assert(dest);
+    pa_assert(a);
+    pa_assert(b);
+
+    for (i = 0; i < a->channels && i < b->channels && i < PA_CHANNELS_MAX; i++)
+        dest->values[i] = pa_sw_volume_divide(a->values[i], b->values[i]);
 
     dest->channels = (uint8_t) i;
 
@@ -181,11 +253,17 @@ pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const
 }
 
 int pa_cvolume_valid(const pa_cvolume *v) {
+    unsigned c;
+
     pa_assert(v);
 
     if (v->channels <= 0 || v->channels > PA_CHANNELS_MAX)
         return 0;
 
+    for (c = 0; c < v->channels; c++)
+        if (v->values[c] == (pa_volume_t) -1)
+            return 0;
+
     return 1;
 }
 
@@ -273,3 +351,17 @@ pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map
     *v = result;
     return v;
 }
+
+int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) {
+
+    pa_assert(v);
+    pa_assert(ss);
+
+    if (!pa_cvolume_valid(v))
+        return 0;
+
+    if (!pa_sample_spec_valid(ss))
+        return 0;
+
+    return v->channels == ss->channels;
+}
index d612c7f91b87c5cef8c673e08e9d3d87ef77100f..75051af5a6368211077319cc9ea83166030689ef 100644 (file)
@@ -116,6 +116,11 @@ typedef struct pa_cvolume {
 /** Return non-zero when *a == *b */
 int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE;
 
+/** Initialize the specified volume and return a pointer to
+ * it. The sample spec will have a defined state but
+ * pa_cvolume_valid() will fail for it. \since 0.9.13 */
+pa_cvolume* pa_cvolume_init(pa_cvolume *a);
+
 /** Set the volume of all channels to PA_VOLUME_NORM */
 #define pa_cvolume_reset(a, n) pa_cvolume_set((a), (n), PA_VOLUME_NORM)
 
@@ -125,12 +130,26 @@ int pa_cvolume_equal(const pa_cvolume *a, const pa_cvolume *b) PA_GCC_PURE;
 /** Set the volume of all channels to the specified parameter */
 pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v);
 
-/** Maximum length of the strings returned by pa_cvolume_snprint() */
-#define PA_CVOLUME_SNPRINT_MAX 64
+/** Maximum length of the strings returned by
+ * pa_cvolume_snprint(). Please note that this value can change with
+ * any release without warning and without being considered API or ABI
+ * breakage. You should not use this definition anywhere where it
+ * might become part of an ABI.*/
+#define PA_CVOLUME_SNPRINT_MAX 320
 
 /** Pretty print a volume structure */
 char *pa_cvolume_snprint(char *s, size_t l, const pa_cvolume *c);
 
+/** Maximum length of the strings returned by
+ * pa_cvolume_snprint_dB(). Please note that this value can change with
+ * any release without warning and without being considered API or ABI
+ * breakage. You should not use this definition anywhere where it
+ * might become part of an ABI. \since 0.9.13 */
+#define PA_SW_CVOLUME_SNPRINT_DB_MAX 448
+
+/** Pretty print a volume structure but show dB values. \since 0.9.13 */
+char *pa_sw_cvolume_snprint_dB(char *s, size_t l, const pa_cvolume *c);
+
 /** Return the average volume of all channels */
 pa_volume_t pa_cvolume_avg(const pa_cvolume *a) PA_GCC_PURE;
 
@@ -149,12 +168,25 @@ int pa_cvolume_channels_equal_to(const pa_cvolume *a, pa_volume_t v) PA_GCC_PURE
 /** Return 1 if the specified volume has all channels on normal level */
 #define pa_cvolume_is_norm(a) pa_cvolume_channels_equal_to((a), PA_VOLUME_NORM)
 
-/** Multiply two volumes specifications, return the result. This uses PA_VOLUME_NORM as neutral element of multiplication. This is only valid for software volumes! */
+/** Multiply two volume specifications, return the result. This uses
+ * PA_VOLUME_NORM as neutral element of multiplication. This is only
+ * valid for software volumes! */
 pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
 
-/** Multiply to per-channel volumes and return the result in *dest. This is only valid for software volumes! */
+/** Multiply two per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! */
 pa_cvolume *pa_sw_cvolume_multiply(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
 
+/** Divide two volume specifications, return the result. This uses
+ * PA_VOLUME_NORM as neutral element of division. This is only valid
+ * for software volumes! If a division by zero is tried the result
+ * will be 0. \since 0.9.13 */
+pa_volume_t pa_sw_volume_divide(pa_volume_t a, pa_volume_t b) PA_GCC_CONST;
+
+/** Multiply to per-channel volumes and return the result in
+ * *dest. This is only valid for software volumes! \since 0.9.13 */
+pa_cvolume *pa_sw_cvolume_divide(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
+
 /** Convert a decibel value to a volume. This is only valid for software volumes! */
 pa_volume_t pa_sw_volume_from_dB(double f) PA_GCC_CONST;
 
@@ -177,6 +209,10 @@ double pa_sw_volume_to_linear(pa_volume_t v) PA_GCC_CONST;
 /** Remap a volume from one channel mapping to a different channel mapping. \since 0.9.12 */
 pa_cvolume *pa_cvolume_remap(pa_cvolume *v, pa_channel_map *from, pa_channel_map *to);
 
+/** Return non-zero if the specified volume is compatible with
+ * the specified sample spec. \since 0.9.13 */
+int pa_cvolume_compatible(const pa_cvolume *v, const pa_sample_spec *ss) PA_GCC_PURE;
+
 PA_C_DECL_END
 
 #endif
index 6b0e1d5670812e010c3eb087ccdedfef30bf1c05..58ceab9171162309dc10810b066253332fb3e353 100644 (file)
@@ -166,6 +166,24 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue,
     return 0;
 }
 
+int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+    size_t *i = data;
+    uint32_t k;
+
+    pa_assert(filename);
+    pa_assert(lvalue);
+    pa_assert(rvalue);
+    pa_assert(data);
+
+    if (pa_atou(rvalue, &k) < 0) {
+        pa_log("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
+        return -1;
+    }
+
+    *i = (size_t) k;
+    return 0;
+}
+
 int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
     int k;
     pa_bool_t *b = data;
index 7eb1fae2251c89e5389bd3cf35a76e036823606a..a5174fce95e17af3cf533bef6f5c2b0e2562aa45 100644 (file)
@@ -39,8 +39,9 @@ typedef struct pa_config_item {
  * NULL */
 int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata);
 
-/* Generic parsers for integers, booleans and strings */
+/* Generic parsers for integers, size_t, booleans and strings */
 int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
+int pa_config_parse_size(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
 int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
 int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata);
 
index 814dff596d15fd838b40d494cf2c7a85a2685d21..1d080e1185f57ad4e42e15186cb029316d9b7b62 100644 (file)
@@ -98,7 +98,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
     pa_assert(c);
     pa_assert(name);
 
-    if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) {
+    if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, FALSE))) {
         if (e->memchunk.memblock)
             pa_memblock_unref(e->memchunk.memblock);
 
@@ -111,7 +111,7 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
     } else {
         e = pa_xnew(pa_scache_entry, 1);
 
-        if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, 1)) {
+        if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, TRUE)) {
             pa_xfree(e);
             return NULL;
         }
@@ -134,9 +134,9 @@ static pa_scache_entry* scache_add_item(pa_core *c, const char *name) {
     e->lazy = FALSE;
     e->last_used_time = 0;
 
-    memset(&e->sample_spec, 0, sizeof(e->sample_spec));
+    pa_sample_spec_init(&e->sample_spec);
     pa_channel_map_init(&e->channel_map);
-    pa_cvolume_reset(&e->volume, PA_CHANNELS_MAX);
+    pa_cvolume_init(&e->volume);
 
     pa_proplist_sets(e->proplist, PA_PROP_MEDIA_ROLE, "event");
 
@@ -159,10 +159,12 @@ int pa_scache_add_item(
     pa_assert(c);
     pa_assert(name);
     pa_assert(!ss || pa_sample_spec_valid(ss));
-    pa_assert(!map || (pa_channel_map_valid(map) && ss && ss->channels == map->channels));
+    pa_assert(!map || (pa_channel_map_valid(map) && ss && pa_channel_map_compatible(map, ss)));
 
-    if (ss && !map)
+    if (ss && !map) {
         pa_channel_map_init_extend(&tmap, ss->channels, PA_CHANNEL_MAP_DEFAULT);
+        map = &tmap;
+    }
 
     if (chunk && chunk->length > PA_SCACHE_ENTRY_SIZE_MAX)
         return -1;
@@ -170,12 +172,13 @@ int pa_scache_add_item(
     if (!(e = scache_add_item(c, name)))
         return -1;
 
-    memset(&e->sample_spec, 0, sizeof(e->sample_spec));
+    pa_sample_spec_init(&e->sample_spec);
     pa_channel_map_init(&e->channel_map);
+    pa_cvolume_init(&e->volume);
 
     if (ss) {
         e->sample_spec = *ss;
-        e->volume.channels = e->sample_spec.channels;
+        pa_cvolume_reset(&e->volume, ss->channels);
     }
 
     if (map)
@@ -310,17 +313,21 @@ int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t
     pa_assert(name);
     pa_assert(sink);
 
-    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1)))
+    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, FALSE)))
         return -1;
 
     if (e->lazy && !e->memchunk.memblock) {
+        pa_channel_map old_channel_map = e->channel_map;
+
         if (pa_sound_file_load(c->mempool, e->filename, &e->sample_spec, &e->channel_map, &e->memchunk) < 0)
             return -1;
 
         pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index);
 
-        if (e->volume.channels > e->sample_spec.channels)
-            e->volume.channels = e->sample_spec.channels;
+        if (pa_cvolume_valid(&e->volume))
+            pa_cvolume_remap(&e->volume, &old_channel_map, &e->channel_map);
+        else
+            pa_cvolume_reset(&e->volume, e->sample_spec.channels);
     }
 
     if (!e->memchunk.memblock)
@@ -383,7 +390,7 @@ uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) {
     pa_assert(c);
     pa_assert(name);
 
-    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0)))
+    if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, FALSE)))
         return PA_IDXSET_INVALID;
 
     return e->index;
index 3e5ea492defa1234bbf6ec220c4732c68b89ab81..dde34d7b2347825acff164798b4dfdb2eabbee02 100644 (file)
@@ -1315,31 +1315,43 @@ static char* make_random_dir(mode_t m) {
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
         "0123456789";
 
-    char fn[24] = "/tmp/pulse-";
+    const char *tmpdir;
+    char *fn;
+    size_t pathlen;
 
-    fn[sizeof(fn)-1] = 0;
+    if (!(tmpdir = getenv("TMPDIR")))
+        if (!(tmpdir = getenv("TMP")))
+            if (!(tmpdir = getenv("TEMP")))
+                tmpdir = getenv("TEMPDIR");
+
+    if (!tmpdir || !pa_is_path_absolute(tmpdir))
+        tmpdir = "/tmp";
+
+    fn = pa_sprintf_malloc("%s/pulse-XXXXXXXXXXXX", tmpdir);
+    pathlen = strlen(fn);
 
     for (;;) {
-        unsigned i;
+        size_t i;
         int r;
         mode_t u;
         int saved_errno;
 
-        for (i = 11; i < sizeof(fn)-1; i++)
+        for (i = pathlen - 12; i < pathlen; i++)
             fn[i] = table[rand() % (sizeof(table)-1)];
 
         u = umask((~m) & 0777);
         r = mkdir(fn, m);
+
         saved_errno = errno;
         umask(u);
+        errno = saved_errno;
 
         if (r >= 0)
-            return pa_xstrdup(fn);
-
-        errno = saved_errno;
+            return fn;
 
         if (errno != EEXIST) {
             pa_log_error("Failed to create random directory %s: %s", fn, pa_cstrerror(errno));
+            pa_xfree(fn);
             return NULL;
         }
     }
@@ -1370,6 +1382,7 @@ static int make_random_dir_and_link(mode_t m, const char *k) {
 char *pa_get_runtime_dir(void) {
     char *d, *k = NULL, *p = NULL, *t = NULL, *mid;
     struct stat st;
+    mode_t m;
 
     /* The runtime directory shall contain dynamic data that needs NOT
      * to be kept accross reboots and is usuallly private to the user,
@@ -1378,10 +1391,9 @@ char *pa_get_runtime_dir(void) {
      * this directory, we link it to a random subdir in /tmp, if it
      * was not explicitly configured. */
 
-    if ((d = getenv("PULSE_RUNTIME_PATH"))) {
-        mode_t m;
+    m = pa_in_system_mode() ? 0755U : 0700U;
 
-        m = pa_in_system_mode() ? 0755U : 0700U;
+    if ((d = getenv("PULSE_RUNTIME_PATH"))) {
 
         if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
             pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
@@ -1394,6 +1406,11 @@ char *pa_get_runtime_dir(void) {
     if (!(d = get_pulse_home()))
         goto fail;
 
+    if (pa_make_secure_dir(d, m, (uid_t) -1, (gid_t) -1) < 0)  {
+        pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
+        goto fail;
+    }
+
     if (!(mid = pa_machine_id())) {
         pa_xfree(d);
         goto fail;
@@ -2334,7 +2351,7 @@ int pa_reset_sigs(int except, ...) {
 int pa_reset_sigsv(const int except[]) {
     int sig;
 
-    for (sig = 1; sig < _NSIG; sig++) {
+    for (sig = 1; sig < NSIG; sig++) {
         pa_bool_t reset = TRUE;
 
         switch (sig) {
@@ -2455,3 +2472,18 @@ char *pa_uname_string(void) {
 
     return pa_sprintf_malloc("%s %s %s %s", u.sysname, u.machine, u.release, u.version);
 }
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+pa_bool_t pa_in_valgrind(void) {
+    static int b = 0;
+
+    /* To make heisenbugs a bit simpler to find we check for $VALGRIND
+     * here instead of really checking whether we run in valgrind or
+     * not. */
+
+    if (b < 1)
+        b = getenv("VALGRIND") ? 2 : 1;
+
+    return b > 1;
+}
+#endif
index df8ce3f85c95e2b6815b3879e69e107f1c6d28b9..fd6ee896611b2167da4b2a887e44c351f9661674 100644 (file)
 #include <pulse/gccmacro.h>
 #include <pulsecore/macro.h>
 
+#ifndef PACKAGE
+#error "Please include config.h before including this file!"
+#endif
+
 struct timeval;
 
 /* These resource limits are pretty new on Linux, let's define them
@@ -193,4 +197,13 @@ pa_bool_t pa_in_system_mode(void);
 char *pa_machine_id(void);
 char *pa_uname_string(void);
 
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+pa_bool_t pa_in_valgrind(void);
+#else
+static inline pa_bool_t pa_in_valgrind(void) {
+    return FALSE;
+}
+#endif
+
 #endif
index bd956ae0b5b287198a3873e865bca53681b42e73..5761bbc73fb302d8e88d64d54543f5a606a98d69 100644 (file)
@@ -66,7 +66,7 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o
 
 static void core_free(pa_object *o);
 
-pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
+pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size) {
     pa_core* c;
     pa_mempool *pool;
     int j;
@@ -74,14 +74,14 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
     pa_assert(m);
 
     if (shared) {
-        if (!(pool = pa_mempool_new(shared))) {
+        if (!(pool = pa_mempool_new(shared, shm_size))) {
             pa_log_warn("failed to allocate shared memory pool. Falling back to a normal memory pool.");
-            shared = 0;
+            shared = FALSE;
         }
     }
 
     if (!shared) {
-        if (!(pool = pa_mempool_new(shared))) {
+        if (!(pool = pa_mempool_new(shared, shm_size))) {
             pa_log("pa_mempool_new() failed.");
             return NULL;
         }
index fb4490f2fc0a5386484ce5e948c770e69add4f80..39559082632cfe30a9cf352e46148f04d7fd068b 100644 (file)
@@ -141,7 +141,7 @@ enum {
     PA_CORE_MESSAGE_MAX
 };
 
-pa_core* pa_core_new(pa_mainloop_api *m, int shared);
+pa_core* pa_core_new(pa_mainloop_api *m, pa_bool_t shared, size_t shm_size);
 
 /* Check whether noone is connected to this core */
 void pa_core_check_idle(pa_core *c);
index 2d8422f9b3f7f827d81679d68442149b898652d2..512dd357dddd671a63533061b1eee17090eb13ba 100644 (file)
@@ -26,6 +26,7 @@
 #include <pulse/gccmacro.h>
 
 #include <pulsecore/once.h>
+#include <pulsecore/core-util.h>
 
 /* A multiple-reader multipler-write lock-free free list implementation */
 
@@ -56,6 +57,8 @@ void* pa_flist_pop(pa_flist*l);
     }                                                                   \
     static void name##_flist_destructor(void) PA_GCC_DESTRUCTOR;        \
     static void name##_flist_destructor(void) {                         \
+        if (!pa_in_valgrind())                                          \
+            return;                                                     \
         if (name##_flist.flist)                                         \
             pa_flist_free(name##_flist.flist, (free_cb));               \
     }                                                                   \
index 2de64069924bfae37a2eedfe36e3616d7de97faa..24a28db74aa48104c76e6bfc798a39d666ac7efc 100644 (file)
@@ -80,7 +80,7 @@ unsigned pa_idxset_trivial_hash_func(const void *p) {
 }
 
 int pa_idxset_trivial_compare_func(const void *a, const void *b) {
-    return a != b;
+    return a < b ? -1 : (a > b ? 1 : 0);
 }
 
 pa_idxset* pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) {
index d73180815d4e18e1b35d1197f32a101799601fdb..b1de6966e9293c125ce0c585a75e87b1e6fe16ed 100644 (file)
@@ -85,6 +85,9 @@ void pa_log_set_ident(const char *p) {
 /* To make valgrind shut up. */
 static void ident_destructor(void) PA_GCC_DESTRUCTOR;
 static void ident_destructor(void) {
+    if (!pa_in_valgrind())
+        return;
+
     pa_xfree(log_ident);
     pa_xfree(log_ident_local);
 }
index fd33b7bb08c7eb8f6f0ad6bec4a4d1da0cfdb408..39e9b587830e346c438f097539c7c072e20afb99 100644 (file)
@@ -208,7 +208,7 @@ typedef int pa_bool_t;
 #define PA_PATH_SEP_CHAR '/'
 #endif
 
-#ifdef __GNUC__
+#if defined(__GNUC__) && defined(__ELF__)
 
 #define PA_WARN_REFERENCE(sym, msg)                  \
     __asm__(".section .gnu.warning." #sym);          \
index 6d12acdca66a98e3e5301633cbd3dd920679cd5e..d9e1bf1ce09925f3a29b61b3f8c3354e2ac02c49 100644 (file)
@@ -261,9 +261,11 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {
         }
     }
 
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-    VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0);
-#endif
+/* #ifdef HAVE_VALGRIND_MEMCHECK_H */
+/*     if (PA_UNLIKELY(pa_in_valgrind())) { */
+/*         VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0); */
+/*     } */
+/* #endif */
 
     return slot;
 }
@@ -534,16 +536,18 @@ static void memblock_free(pa_memblock *b) {
 
             call_free = b->type == PA_MEMBLOCK_POOL_EXTERNAL;
 
+/* #ifdef HAVE_VALGRIND_MEMCHECK_H */
+/*             if (PA_UNLIKELY(pa_in_valgrind())) { */
+/*                 VALGRIND_FREELIKE_BLOCK(slot, b->pool->block_size); */
+/*             } */
+/* #endif */
+
             /* The free list dimensions should easily allow all slots
              * to fit in, hence try harder if pushing this slot into
              * the free list fails */
             while (pa_flist_push(b->pool->free_slots, slot) < 0)
                 ;
 
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-            VALGRIND_FREELIKE_BLOCK(slot, b->pool->block_size);
-#endif
-
             if (call_free)
                 if (pa_flist_push(PA_STATIC_FLIST_GET(unused_memblocks), b) < 0)
                     pa_xfree(b);
@@ -680,8 +684,9 @@ static void memblock_replace_import(pa_memblock *b) {
         pa_mutex_unlock(seg->import->mutex);
 }
 
-pa_mempool* pa_mempool_new(pa_bool_t shared) {
+pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size) {
     pa_mempool *p;
+    char t1[64], t2[64];
 
     p = pa_xnew(pa_mempool, 1);
 
@@ -692,13 +697,26 @@ pa_mempool* pa_mempool_new(pa_bool_t shared) {
     if (p->block_size < PA_PAGE_SIZE)
         p->block_size = PA_PAGE_SIZE;
 
-    p->n_blocks = PA_MEMPOOL_SLOTS_MAX;
+    if (size <= 0)
+        p->n_blocks = PA_MEMPOOL_SLOTS_MAX;
+    else {
+        p->n_blocks = (unsigned) (size / p->block_size);
+
+        if (p->n_blocks < 2)
+            p->n_blocks = 2;
+    }
 
     if (pa_shm_create_rw(&p->memory, p->n_blocks * p->block_size, shared, 0700) < 0) {
         pa_xfree(p);
         return NULL;
     }
 
+    pa_log_debug("Using %s memory pool with %u slots of size %s each, total size is %s",
+                 p->memory.shared ? "shared" : "private",
+                 p->n_blocks,
+                 pa_bytes_snprint(t1, sizeof(t1), (unsigned) p->block_size),
+                 pa_bytes_snprint(t2, sizeof(t2), (unsigned) (p->n_blocks * p->block_size)));
+
     memset(&p->stat, 0, sizeof(p->stat));
     pa_atomic_store(&p->n_init, 0);
 
index efe55b0289fa6d827f448b2fa982cc0198e42c3c..b1eab2a9645edc4383182b4622a701f27badb5a8 100644 (file)
@@ -117,7 +117,7 @@ pa_mempool * pa_memblock_get_pool(pa_memblock *b);
 pa_memblock *pa_memblock_will_need(pa_memblock *b);
 
 /* The memory block manager */
-pa_mempool* pa_mempool_new(pa_bool_t shared);
+pa_mempool* pa_mempool_new(pa_bool_t shared, size_t size);
 void pa_mempool_free(pa_mempool *p);
 const pa_mempool_stat* pa_mempool_get_stat(pa_mempool *p);
 void pa_mempool_vacuum(pa_mempool *p);
index ad697ed59677b5f70e0d01b24a3850845bbc9597..ecd8def8d6485310d174dc48aba84a21f2a807db 100644 (file)
@@ -51,6 +51,7 @@ static pa_bool_t is_valid_char(char c) {
         (c >= 'A' && c <= 'Z') ||
         (c >= '0' && c <= '9') ||
         c == '.' ||
+        c == '-' ||
         c == '_';
 }
 
@@ -97,7 +98,7 @@ void pa_namereg_free(pa_core *c) {
     pa_hashmap_free(c->namereg, NULL, NULL);
 }
 
-const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, int fail) {
+const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, pa_bool_t fail) {
     struct namereg_entry *e;
     char *n = NULL;
 
index 3c1de8e73226f80b5f2a179d5485180a102bc271..f45810063cc752277559a0b4d12ee69aff5fef78 100644 (file)
@@ -35,7 +35,7 @@ typedef enum pa_namereg_type {
 
 void pa_namereg_free(pa_core *c);
 
-const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, int fail);
+const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, pa_bool_t fail);
 void pa_namereg_unregister(pa_core *c, const char *name);
 void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type, pa_bool_t autoload);
 int pa_namereg_set_default(pa_core*c, const char *name, pa_namereg_type_t type);
diff --git a/src/pulsecore/prioq.c b/src/pulsecore/prioq.c
new file mode 100644 (file)
index 0000000..693dc51
--- /dev/null
@@ -0,0 +1,256 @@
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008 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 <pulse/xmalloc.h>
+
+#include <pulsecore/flist.h>
+
+#include "prioq.h"
+
+struct pa_prioq_item {
+    void *value;
+    unsigned idx;
+};
+
+struct pa_prioq {
+    pa_prioq_item **items;
+    unsigned n_items;
+    unsigned n_allocated;
+    pa_compare_func_t compare_func;
+};
+
+PA_STATIC_FLIST_DECLARE(items, 0, pa_xfree);
+
+pa_prioq *pa_prioq_new(pa_compare_func_t compare_func) {
+
+    pa_prioq *q;
+
+    q = pa_xnew(pa_prioq, 1);
+    q->compare_func = compare_func;
+    q->n_items = 0;
+    q->n_allocated = 64;
+    q->items = pa_xnew(pa_prioq_item*, q->n_allocated);
+
+    return q;
+}
+
+void pa_prioq_free(pa_prioq *q, pa_free2_cb_t free_cb, void *userdata) {
+    pa_prioq_item **i, **e;
+
+    pa_assert(q);
+
+    for (i = q->items, e = q->items + q->n_items; i < e; i++) {
+
+        if (!*i)
+            continue;
+
+        if (free_cb)
+            free_cb((*i)->value, userdata);
+
+        pa_xfree(*i);
+    }
+
+    pa_xfree(q->items);
+    pa_xfree(q);
+}
+
+static void shuffle_up(pa_prioq *q, pa_prioq_item *i) {
+    unsigned j;
+
+    pa_assert(q);
+    pa_assert(i);
+
+    j = i->idx;
+
+    while (j > 0) {
+        unsigned k;
+
+        k = (j-1)/2;
+
+        if (q->compare_func(q->items[k]->value, i->value) < 0)
+            break;
+
+        q->items[k]->idx = j;
+        q->items[j] = q->items[k];
+
+        j = k;
+    }
+
+    i->idx = j;
+    q->items[j] = i;
+
+}
+
+pa_prioq_item* pa_prioq_put(pa_prioq *q, void *p) {
+    pa_prioq_item *i;
+
+    pa_assert(q);
+
+    if (q->n_items >= q->n_allocated) {
+        q->n_allocated = PA_MAX(q->n_items+1, q->n_allocated)*2;
+        q->items = pa_xrealloc(q->items, sizeof(pa_prioq_item*) * q->n_allocated);
+    }
+
+    if (!(i = pa_flist_pop(PA_STATIC_FLIST_GET(items))))
+        i = pa_xnew(pa_prioq_item, 1);
+
+    i->value = p;
+    i->idx = q->n_items++;
+
+    shuffle_up(q, i);
+
+    return i;
+}
+
+void* pa_prioq_peek(pa_prioq *q) {
+    pa_assert(q);
+
+    if (q->n_items <= 0)
+        return NULL;
+
+    return q->items[0]->value;
+}
+
+void* pa_prioq_pop(pa_prioq *q){
+    pa_assert(q);
+
+    if (q->n_items <= 0)
+        return NULL;
+
+    return pa_prioq_remove(q, q->items[0]);
+}
+
+static void swap(pa_prioq *q, unsigned j, unsigned k) {
+    pa_prioq_item *t;
+
+    pa_assert(q);
+    pa_assert(j < q->n_items);
+    pa_assert(k < q->n_items);
+
+    pa_assert(q->items[j]->idx == j);
+    pa_assert(q->items[k]->idx == k);
+
+    t = q->items[j];
+
+    q->items[j]->idx = k;
+    q->items[j] = q->items[k];
+
+    q->items[k]->idx = j;
+    q->items[k] = t;
+}
+
+static void shuffle_down(pa_prioq *q, unsigned idx) {
+
+    pa_assert(q);
+    pa_assert(idx < q->n_items);
+
+    for (;;) {
+        unsigned j, k, s;
+
+        k = (idx+1)*2; /* right child */
+        j = k-1;       /* left child */
+
+        if (j >= q->n_items)
+            break;
+
+        if (q->compare_func(q->items[j]->value, q->items[idx]->value) < 0)
+
+            /* So our left child is smaller than we are, let's
+             * remember this fact */
+            s = j;
+        else
+            s = idx;
+
+        if (k < q->n_items &&
+            q->compare_func(q->items[k]->value, q->items[s]->value) < 0)
+
+            /* So our right child is smaller than we are, let's
+             * remember this fact */
+            s = k;
+
+        /* s now points to the smallest of the three items */
+
+        if (s == idx)
+            /* No swap necessary, we're done */
+            break;
+
+        swap(q, idx, s);
+        idx = s;
+    }
+}
+
+void* pa_prioq_remove(pa_prioq *q, pa_prioq_item *i) {
+    void *p;
+
+    pa_assert(q);
+    pa_assert(i);
+    pa_assert(q->n_items >= 1);
+
+    p = i->value;
+
+    if (q->n_items-1 == i->idx) {
+        /* We are the last entry, so let's just remove us and good */
+        q->n_items--;
+
+    } else {
+
+        /* We are not the last entry, we need to replace ourselves
+         * with the last node and reshuffle */
+
+        q->items[i->idx] = q->items[q->n_items-1];
+        q->items[i->idx]->idx = i->idx;
+        q->n_items--;
+
+        shuffle_down(q, i->idx);
+    }
+
+    if (pa_flist_push(PA_STATIC_FLIST_GET(items), i) < 0)
+        pa_xfree(i);
+
+    return p;
+}
+
+unsigned pa_prioq_size(pa_prioq *q) {
+    pa_assert(q);
+
+    return q->n_items;
+}
+
+pa_bool_t pa_prioq_isempty(pa_prioq *q) {
+    pa_assert(q);
+
+    return q->n_items == 0;
+}
+
+void pa_prioq_reshuffle(pa_prioq *q, pa_prioq_item *i) {
+    pa_assert(q);
+    pa_assert(i);
+
+    /* This will move the entry down as far as necessary */
+    shuffle_down(q, i->idx);
+
+    /* And this will move the entry up as far as necessary */
+    shuffle_up(q, i);
+}
diff --git a/src/pulsecore/prioq.h b/src/pulsecore/prioq.h
new file mode 100644 (file)
index 0000000..fd3550b
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef foopulsecoreprioqhfoo
+#define foopulsecoreprioqhfoo
+
+/***
+  This file is part of PulseAudio.
+
+  Copyright 2008 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.1 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
+  Lesser 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 <inttypes.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/idxset.h>
+
+/* A heap-based priority queue. Removal and insertion is O(log
+ * n). Removal can happen a the top or at any position referenced by a
+ * pa_prioq_item.  */
+
+typedef struct pa_prioq pa_prioq;
+typedef struct pa_prioq_item pa_prioq_item;
+
+/* Instantiate a new prioq with the specified comparison functions */
+pa_prioq* pa_prioq_new(pa_compare_func_t compare_func);
+
+/* Free the prioq. When the prioq is not empty the specified function is called for every entry contained */
+void pa_prioq_free(pa_prioq *q, pa_free2_cb_t free_cb, void *userdata);
+
+/* Store a new item in the prioq. */
+pa_prioq_item* pa_prioq_put(pa_prioq *q, void* data);
+
+/* Get the item on the top of the queue, but don't remove it from the queue*/
+void* pa_prioq_peek(pa_prioq*q);
+
+/* Get the item on the top of the queue, and remove it from thq queue */
+void* pa_prioq_pop(pa_prioq*q);
+
+/* Remove an arbitrary from theq prioq, returning it's data */
+void* pa_prioq_remove(pa_prioq*q, pa_prioq_item *i);
+
+/* The priority of an item was modified. Adjustthe queue to that */
+void pa_prioq_reshuffle(pa_prioq *q, pa_prioq_item *i);
+
+/* Return the current number of items in the prioq */
+unsigned pa_prioq_size(pa_prioq*s);
+
+/* Return TRUE of the prioq is empty */
+pa_bool_t pa_prioq_isempty(pa_prioq *s);
+
+#endif
index 6005775ed1779c3efea7d9c06938930d5d2cbe5a..4d505f57bee5250e4d859cd75c36d0fae46f03e5 100644 (file)
@@ -37,7 +37,7 @@
 
 void pa_init_proplist(pa_proplist *p) {
     int a, b;
-#ifndef HAVE_DECL_ENVIRON
+#if !HAVE_DECL_ENVIRON
     extern char **environ;
 #endif
     char **e;
index 6ccee571413ed5639ec0830201d21a269f5e47df..778aab57938e81ae475c5e89c387b99c43f16267 100644 (file)
@@ -2192,6 +2192,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
         if (c->version < 10 || (c->version >= 13 && !shm_on_remote))
             do_shm = FALSE;
 
+#ifdef HAVE_CREDS
     if (do_shm) {
         /* Only enable SHM if both sides are owned by the same
          * user. This is a security measure because otherwise data
@@ -2201,6 +2202,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
         if (!(creds = pa_pdispatch_creds(pd)) || getuid() != creds->uid)
             do_shm = FALSE;
     }
+#endif
 
     pa_log_debug("Negotiated SHM: %s", pa_yes_no(do_shm));
     pa_pstream_enable_shm(c->pstream, do_shm);
@@ -3166,6 +3168,10 @@ static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uin
     CHECK_VALIDITY(c->pstream, playback_stream_isinstance(s), tag, PA_ERR_NOENTITY);
 
     pa_sink_input_cork(s->sink_input, b);
+
+    if (b)
+        s->is_underrun = TRUE;
+
     pa_pstream_send_simple_ack(c->pstream, tag);
 }
 
index 65e67737d3e11258707324d92db1828adb22d0df..743bf2ee7c4d5db9607d8c9822b23709c109dc98 100644 (file)
@@ -173,7 +173,7 @@ static int do_read(connection *c) {
     }
 
     if (!c->playback.current_memblock) {
-        pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, 0));
+        pa_assert_se(c->playback.current_memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) -1));
         c->playback.memblock_index = 0;
 
         space = pa_memblock_get_length(c->playback.current_memblock);
@@ -492,6 +492,8 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
     c->parent.parent.free = connection_free;
     c->parent.process_msg = connection_process_msg;
     c->io = io;
+    pa_iochannel_set_callback(c->io, io_callback, c);
+
     c->sink_input = NULL;
     c->source_output = NULL;
     c->input_memblockq = c->output_memblockq = NULL;
@@ -610,7 +612,6 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
         pa_source_output_put(c->source_output);
     }
 
-    pa_iochannel_set_callback(c->io, io_callback, c);
     pa_idxset_put(p->connections, c, NULL);
 
     return;
@@ -689,6 +690,9 @@ pa_simple_options* pa_simple_options_new(void) {
     o = pa_xnew0(pa_simple_options, 1);
     PA_REFCNT_INIT(o);
 
+    o->record = FALSE;
+    o->playback = TRUE;
+
     return o;
 }
 
@@ -733,14 +737,14 @@ int pa_simple_options_parse(pa_simple_options *o, pa_core *c, pa_modargs *ma) {
     pa_xfree(o->default_sink);
     o->default_sink = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 
-    enabled = FALSE;
+    enabled = o->record;
     if (pa_modargs_get_value_boolean(ma, "record", &enabled) < 0) {
         pa_log("record= expects a boolean argument.");
         return -1;
     }
     o->record = enabled;
 
-    enabled = TRUE;
+    enabled = o->playback;
     if (pa_modargs_get_value_boolean(ma, "playback", &enabled) < 0) {
         pa_log("playback= expects a boolean argument.");
         return -1;
index b4234af5f71e0c1e3425bad8dadd78818cb78089..7b9ac7bc99eba0fe24a07d52297c4cbf41b73033 100644 (file)
@@ -98,56 +98,62 @@ void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {
     return p;
 }
 
-static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_sample_spec *spec) {
-    unsigned k;
-
-    pa_assert(streams);
-    pa_assert(spec);
+static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
+    unsigned channel;
 
-    for (k = 0; k < nstreams; k++) {
-        unsigned channel;
+    pa_assert(linear);
+    pa_assert(volume);
 
-        for (channel = 0; channel < spec->channels; channel++) {
-            pa_mix_info *m = streams + k;
-            m->linear[channel].i = (int32_t) (pa_sw_volume_to_linear(m->volume.values[channel]) * 0x10000);
-        }
-    }
+    for (channel = 0; channel < volume->channels; channel++)
+        linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
 }
 
-static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
+static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
     unsigned channel;
 
     pa_assert(linear);
     pa_assert(volume);
 
     for (channel = 0; channel < volume->channels; channel++)
-        linear[channel] = (int32_t) (pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);
+        linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
 }
 
-static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_sample_spec *spec) {
-    unsigned k;
+static void calc_linear_integer_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
+    unsigned k, channel;
+    float linear[PA_CHANNELS_MAX];
 
     pa_assert(streams);
     pa_assert(spec);
+    pa_assert(volume);
+
+    calc_linear_float_volume(linear, volume);
 
     for (k = 0; k < nstreams; k++) {
-        unsigned channel;
 
         for (channel = 0; channel < spec->channels; channel++) {
             pa_mix_info *m = streams + k;
-            m->linear[channel].f = (float) pa_sw_volume_to_linear(m->volume.values[channel]);
+            m->linear[channel].i = (int32_t) lrint(pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel] * 0x10000);
         }
     }
 }
 
-static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
-    unsigned channel;
+static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
+    unsigned k, channel;
+    float linear[PA_CHANNELS_MAX];
 
-    pa_assert(linear);
+    pa_assert(streams);
+    pa_assert(spec);
     pa_assert(volume);
 
-    for (channel = 0; channel < volume->channels; channel++)
-        linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);
+    calc_linear_float_volume(linear, volume);
+
+    for (k = 0; k < nstreams; k++) {
+
+        for (channel = 0; channel < spec->channels; channel++) {
+            pa_mix_info *m = streams + k;
+            m->linear[channel].f = (float) (pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel]);
+        }
+    }
 }
 
 size_t pa_mix(
@@ -190,10 +196,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_S16NE:{
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int32_t sum = 0;
@@ -203,18 +207,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     int32_t v, cv = m->linear[channel].i;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = *((int16_t*) m->ptr);
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = *((int16_t*) m->ptr);
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
                 *((int16_t*) data) = (int16_t) sum;
 
@@ -229,10 +231,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_S16RE:{
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int32_t sum = 0;
@@ -242,18 +242,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     int32_t v, cv = m->linear[channel].i;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = PA_INT16_SWAP(*((int16_t*) m->ptr));
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = PA_INT16_SWAP(*((int16_t*) m->ptr));
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + sizeof(int16_t);
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
                 *((int16_t*) data) = PA_INT16_SWAP((int16_t) sum);
 
@@ -268,10 +266,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_S32NE:{
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int64_t sum = 0;
@@ -279,21 +275,19 @@ size_t pa_mix(
 
                 for (i = 0; i < nstreams; i++) {
                     pa_mix_info *m = streams + i;
-                    int64_t v;
                     int32_t cv = m->linear[channel].i;
+                    int64_t v;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = *((int32_t*) m->ptr);
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = *((int32_t*) m->ptr);
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
                 *((int32_t*) data) = (int32_t) sum;
 
@@ -308,10 +302,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_S32RE:{
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int64_t sum = 0;
@@ -319,21 +311,19 @@ size_t pa_mix(
 
                 for (i = 0; i < nstreams; i++) {
                     pa_mix_info *m = streams + i;
-                    int64_t v;
                     int32_t cv = m->linear[channel].i;
+                    int64_t v;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = PA_INT32_SWAP(*((int32_t*) m->ptr));
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = PA_INT32_SWAP(*((int32_t*) m->ptr));
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + sizeof(int32_t);
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
                 *((int32_t*) data) = PA_INT32_SWAP((int32_t) sum);
 
@@ -348,10 +338,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_U8: {
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int32_t sum = 0;
@@ -361,18 +349,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     int32_t v, cv = m->linear[channel].i;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = (int32_t) *((uint8_t*) m->ptr) - 0x80;
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + 1;
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x80, 0x7F);
                 *((uint8_t*) data) = (uint8_t) (sum + 0x80);
 
@@ -387,10 +373,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_ULAW: {
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int32_t sum = 0;
@@ -400,18 +384,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     int32_t v, cv = m->linear[channel].i;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = (int32_t) st_ulaw2linear16(*((uint8_t*) m->ptr));
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + 1;
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
                 *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);
 
@@ -426,10 +408,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_ALAW: {
             unsigned channel = 0;
-            int32_t linear[PA_CHANNELS_MAX];
 
-            calc_linear_integer_stream_volumes(streams, nstreams, spec);
-            calc_linear_integer_volume(linear, volume);
+            calc_linear_integer_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 int32_t sum = 0;
@@ -439,18 +419,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     int32_t v, cv = m->linear[channel].i;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
-                        v = (v * cv) / 0x10000;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = (int32_t) st_alaw2linear16(*((uint8_t*) m->ptr));
+                    v = (v * cv) / 0x10000;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + 1;
                 }
 
-                sum = (sum * linear[channel]) / 0x10000;
                 sum = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
                 *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);
 
@@ -465,10 +443,8 @@ size_t pa_mix(
 
         case PA_SAMPLE_FLOAT32NE: {
             unsigned channel = 0;
-            float linear[PA_CHANNELS_MAX];
 
-            calc_linear_float_stream_volumes(streams, nstreams, spec);
-            calc_linear_float_volume(linear, volume);
+            calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 float sum = 0;
@@ -478,18 +454,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     float v, cv = m->linear[channel].f;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else {
-                        v = *((float*) m->ptr);
-                        v *= cv;
-                    }
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = *((float*) m->ptr);
+                    v *= cv;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + sizeof(float);
                 }
 
-                sum *= linear[channel];
                 *((float*) data) = sum;
 
                 data = (uint8_t*) data + sizeof(float);
@@ -505,8 +479,7 @@ size_t pa_mix(
             unsigned channel = 0;
             float linear[PA_CHANNELS_MAX];
 
-            calc_linear_float_stream_volumes(streams, nstreams, spec);
-            calc_linear_float_volume(linear, volume);
+            calc_linear_float_stream_volumes(streams, nstreams, volume, spec);
 
             while (data < end) {
                 float sum = 0;
@@ -516,16 +489,16 @@ size_t pa_mix(
                     pa_mix_info *m = streams + i;
                     float v, cv = m->linear[channel].f;
 
-                    if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(linear[channel] <= 0))
-                        v = 0;
-                    else
-                        v = PA_FLOAT32_SWAP(*(float*) m->ptr) *cv;
+                    if (PA_UNLIKELY(cv <= 0))
+                        continue;
 
+                    v = PA_FLOAT32_SWAP(*(float*) m->ptr);
+                    v *= cv;
                     sum += v;
+
                     m->ptr = (uint8_t*) m->ptr + sizeof(float);
                 }
 
-                sum *= linear[channel];
                 *((float*) data) = PA_FLOAT32_SWAP(sum);
 
                 data = (uint8_t*) data + sizeof(float);
index 693d529bc4044fb30a46543caa82e594c80a33e3..159c4655f010c9454f95261294a0b3a9cd2927f1 100644 (file)
@@ -111,7 +111,7 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
         float v = *(a++);
 
         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
-        s = (int16_t) (v * 0x7FFF);
+        s = (int16_t) lrintf(v * 0x7FFF);
         *(b++) = INT16_TO(s);
     }
 
@@ -134,7 +134,7 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
         float v = *(a++);
 
         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) ((double) v * (double) 0x7FFFFFFF);
+        s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
         *(b++) = INT32_TO(s);
     }
 
@@ -153,8 +153,7 @@ void pa_sconv_s16le_to_float32re(unsigned n, const int16_t *a, float *b) {
     for (; n > 0; n--) {
         int16_t s = *(a++);
         float k = ((float) INT16_FROM(s))/0x7FFF;
-        uint32_t *j = (uint32_t*) &k;
-        *j = PA_UINT32_SWAP(*j);
+        k = PA_FLOAT32_SWAP(k);
         *(b++) = k;
     }
 }
@@ -166,8 +165,7 @@ void pa_sconv_s32le_to_float32re(unsigned n, const int32_t *a, float *b) {
     for (; n > 0; n--) {
         int32_t s = *(a++);
         float k = (float) (((double) INT32_FROM(s))/0x7FFFFFFF);
-        uint32_t *j = (uint32_t*) &k;
-        *j = PA_UINT32_SWAP(*j);
+        k = PA_FLOAT32_SWAP(k);
         *(b++) = k;
     }
 }
@@ -179,10 +177,9 @@ void pa_sconv_s16le_from_float32re(unsigned n, const float *a, int16_t *b) {
     for (; n > 0; n--) {
         int16_t s;
         float v = *(a++);
-        uint32_t *j = (uint32_t*) &v;
-        *j = PA_UINT32_SWAP(*j);
+        v = PA_FLOAT32_SWAP(v);
         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int16_t) (v * 0x7FFF);
+        s = (int16_t) lrintf(v * 0x7FFF);
         *(b++) = INT16_TO(s);
     }
 }
@@ -194,10 +191,9 @@ void pa_sconv_s32le_from_float32re(unsigned n, const float *a, int32_t *b) {
     for (; n > 0; n--) {
         int32_t s;
         float v = *(a++);
-        uint32_t *j = (uint32_t*) &v;
-        *j = PA_UINT32_SWAP(*j);
+        v = PA_FLOAT32_SWAP(v);
         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
-        s = (int32_t) ((double) v * 0x7FFFFFFF);
+        s = (int32_t) lrint((double) v * 0x7FFFFFFF);
         *(b++) = INT32_TO(s);
     }
 }
index 733a46ae8aa4bebcfc1a6f5126f2e6c33fd4be02..6c4d420e6cb85586c4971d63acc802241e602d68 100644 (file)
@@ -130,7 +130,7 @@ static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {
         float v = *(a++);
         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
         v *= 0x1FFF;
-        *(b++) = st_14linear2ulaw((int16_t) v);
+        *(b++) = st_14linear2ulaw((int16_t) lrintf(v));
     }
 }
 
@@ -168,7 +168,7 @@ static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {
         float v = *a;
         v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
         v *= 0xFFF;
-        *b = st_13linear2alaw((int16_t) v);
+        *b = st_13linear2alaw((int16_t) lrintf(v));
     }
 }
 
index 326a7e2ce1651c6ace61eacffff0701805e99848..4f70347fdd5b5ecb6efe3ef64ac956315e73dddc 100644 (file)
@@ -1030,6 +1030,9 @@ void pa_sink_input_set_state_within_thread(pa_sink_input *i, pa_sink_input_state
 
     } else if (uncorking) {
 
+        i->thread_info.underrun_for = (uint64_t) -1;
+        i->thread_info.playing_for = 0;
+
         pa_log_debug("Requesting rewind due to uncorking");
 
         /* OK, we're being uncorked. Make sure we're not rewound when
index 6fa22dc246abce69227da4fd42b66229f6821e09..e04fc08af61f1a32fd592058fc1856a2830d51d3 100644 (file)
@@ -663,7 +663,6 @@ void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) {
         pa_sw_cvolume_multiply(&volume, &s->thread_info.soft_volume, &info[0].volume);
 
         if (s->thread_info.soft_muted || !pa_cvolume_is_norm(&volume)) {
-            pa_log("adjusting volume ");
             pa_memchunk_make_writable(result, 0);
             if (s->thread_info.soft_muted || pa_cvolume_is_muted(&volume))
                 pa_silence_memchunk(result, &s->sample_spec);
index 87e850d67eae41221c92c595c6655fd70d1695ad..eabe9ba4967163e278c74e2d6e9a4effbc35e18a 100644 (file)
@@ -25,6 +25,7 @@
 
 #include <pulse/def.h>
 #include <pulsecore/once.h>
+#include <pulsecore/core-util.h>
 
 #ifndef PACKAGE
 #error "Please include config.h before including this file!"
@@ -69,6 +70,8 @@ void *pa_tls_set(pa_tls *t, void *userdata);
     static void name##_tls_destructor(void) PA_GCC_DESTRUCTOR;          \
     static void name##_tls_destructor(void) {                           \
         static void (*_free_cb)(void*) = free_cb;                       \
+        if (!pa_in_valgrind())                                          \
+            return;                                                     \
         if (!name##_tls.tls)                                            \
             return;                                                     \
         if (_free_cb) {                                                 \
index b165f4a8cc5eee75f916e30cf51ad64a27d706d2..6a2ffaa67ad8e90b0f8cdee4e7b97ac7cae40bf7 100644 (file)
@@ -284,7 +284,7 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {
         /* The requested point is right of the point where we wanted
          * to be on track again, thus just linearly estimate */
 
-        t = (int64_t) s->py + (int64_t) (s->dp * (double) (x - s->px));
+        t = (int64_t) s->py + (int64_t) llrint(s->dp * (double) (x - s->px));
 
         if (t < 0)
             t = 0;
@@ -313,7 +313,7 @@ static void estimate(pa_smoother *s, pa_usec_t x, pa_usec_t *y, double *deriv) {
         /* Move back from origin */
         ty += (double) s->ey;
 
-        *y = ty >= 0 ? (pa_usec_t) ty : 0;
+        *y = ty >= 0 ? (pa_usec_t) lrint(ty) : 0;
 
         /* Horner scheme */
         if (deriv)
@@ -360,7 +360,7 @@ void pa_smoother_put(pa_smoother *s, pa_usec_t x, pa_usec_t y) {
 
     /* And calculate when we want to be on track again */
     s->px = s->ex + s->adjust_time;
-    s->py = s->ry + (pa_usec_t) (s->dp * (double) s->adjust_time);
+    s->py = s->ry + (pa_usec_t) lrint(s->dp * (double) s->adjust_time);
 
     s->abc_valid = FALSE;
 
@@ -456,7 +456,7 @@ pa_usec_t pa_smoother_translate(pa_smoother *s, pa_usec_t x, pa_usec_t y_delay)
 
 /*     pa_log_debug("translate(%llu) = %llu (%0.2f)", (unsigned long long) y_delay, (unsigned long long) ((double) y_delay / nde), nde); */
 
-    return (pa_usec_t) ((double) y_delay / nde);
+    return (pa_usec_t) lrint((double) y_delay / nde);
 }
 
 void pa_smoother_reset(pa_smoother *s) {
index d71eff1c1a32031519868bf8e2405f7acd6c9757..4a72f5a3f624a5bbe9d84b3a03848dae2f2364d2 100644 (file)
@@ -205,7 +205,7 @@ int main(int argc, char *argv[]) {
     oil_init();
     pa_log_set_maximal_level(PA_LOG_DEBUG);
 
-    pa_assert_se(pool = pa_mempool_new(FALSE));
+    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
     pa_assert_se(envelope = pa_envelope_new(&ss));
 
     block = generate_block(pool, &ss);
index c066582233d62fe9ed39cf6ee3f9f8a46432f1a6..92e3e14e32b86d8bae95b096ecbd97dee44d17cb 100644 (file)
@@ -41,7 +41,7 @@ int main(int argc, char *argv[]) {
     pa_mcalign *a;
     pa_memchunk c;
 
-    p = pa_mempool_new(0);
+    p = pa_mempool_new(FALSE, 0);
 
     a = pa_mcalign_new(11);
 
index 6da1b1e9f14dc0a6717312656c270246302412ca..37b5b403a31d458d072c18fc0f6da6de49bafee3 100644 (file)
@@ -78,9 +78,9 @@ int main(int argc, char *argv[]) {
 
     const char txt[] = "This is a test!";
 
-    pool_a = pa_mempool_new(1);
-    pool_b = pa_mempool_new(1);
-    pool_c = pa_mempool_new(1);
+    pool_a = pa_mempool_new(TRUE, 0);
+    pool_b = pa_mempool_new(TRUE, 0);
+    pool_c = pa_mempool_new(TRUE, 0);
 
     pa_mempool_get_shm_id(pool_a, &id_a);
     pa_mempool_get_shm_id(pool_b, &id_b);
index 7bf992a19e18042d3b84858fbe177ccc036864f3..c53945b44c02b1d83b1a287f157db3a1aa6cb29b 100644 (file)
@@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
 
     pa_log_set_maximal_level(PA_LOG_DEBUG);
 
-    p = pa_mempool_new(0);
+    p = pa_mempool_new(FALSE, 0);
 
     silence.memblock = pa_memblock_new_fixed(p, (char*)  "__", 2, 1);
     assert(silence.memblock);
index 544121fde54cd47107b0ad294cab4064b10797df..cc21ab0345e1bc473661a6da3d2f5f0d391971c2 100644 (file)
@@ -201,7 +201,7 @@ int main(int argc, char *argv[]) {
     oil_init();
     pa_log_set_maximal_level(PA_LOG_DEBUG);
 
-    pa_assert_se(pool = pa_mempool_new(FALSE));
+    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
 
     a.channels = 1;
     a.rate = 44100;
@@ -221,6 +221,8 @@ int main(int argc, char *argv[]) {
         i.length = pa_memblock_get_length(i.memblock);
         i.index = 0;
 
+        dump_block(&a, &i);
+
         /* Make a copy */
         j = i;
         pa_memblock_ref(j.memblock);
@@ -229,6 +231,8 @@ int main(int argc, char *argv[]) {
         /* Adjust volume of the copy */
         pa_volume_memchunk(&j, &a, &v);
 
+        dump_block(&a, &j);
+
         m[0].chunk = i;
         m[0].volume.values[0] = PA_VOLUME_NORM;
         m[0].volume.channels = a.channels;
@@ -244,8 +248,6 @@ int main(int argc, char *argv[]) {
         pa_mix(m, 2, ptr, k.length, &a, NULL, FALSE);
         pa_memblock_release(k.memblock);
 
-        dump_block(&a, &i);
-        dump_block(&a, &j);
         dump_block(&a, &k);
 
         pa_memblock_unref(i.memblock);
diff --git a/src/tests/prioq-test.c b/src/tests/prioq-test.c
new file mode 100644 (file)
index 0000000..120b512
--- /dev/null
@@ -0,0 +1,44 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulsecore/prioq.h>
+#include <pulsecore/macro.h>
+
+#define N 1024
+
+int main(int argc, char *argv[]) {
+    pa_prioq *q;
+    unsigned i;
+
+    srand(0);
+
+    q = pa_prioq_new(pa_idxset_trivial_compare_func);
+
+    /* Fill in 1024 */
+    for (i = 0; i < N; i++)
+        pa_prioq_put(q, PA_UINT_TO_PTR((unsigned) rand()));
+
+    /* Remove half of it again */
+    for (i = 0; i < N/2; i++){
+        unsigned u = PA_PTR_TO_UINT(pa_prioq_pop(q));
+        pa_log("%16u", u);
+    }
+
+    pa_log("Refilling");
+
+    /* Fill in another 1024 */
+    for (i = 0; i < N; i++)
+        pa_prioq_put(q, PA_UINT_TO_PTR((unsigned) rand()));
+
+
+    /* Remove everything */
+    while (!pa_prioq_isempty(q)) {
+        unsigned u = PA_PTR_TO_UINT(pa_prioq_pop(q));
+        pa_log("%16u", u);
+    }
+
+    pa_prioq_free(q, NULL, NULL);
+
+    return 0;
+}
index 4777c150958b838e0aacf7e8b724d2d5a9c54945..3538d7d4664297b7d77135ba078bcc349be38270 100644 (file)
@@ -58,7 +58,7 @@ int main(int argc, char *argv[]) {
     oil_init();
     pa_log_set_maximal_level(PA_LOG_DEBUG);
 
-    pa_assert_se(pool = pa_mempool_new(FALSE));
+    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
 
     for (i = 0; maps[i].channels > 0; i++)
         for (j = 0; maps[j].channels > 0; j++) {
index 6959127b5a032b527dd9e55ae496d5bb780c26b9..2d59186760b70c545ac889073362edfd6df41fa1 100644 (file)
@@ -201,7 +201,7 @@ int main(int argc, char *argv[]) {
     oil_init();
     pa_log_set_maximal_level(PA_LOG_DEBUG);
 
-    pa_assert_se(pool = pa_mempool_new(FALSE));
+    pa_assert_se(pool = pa_mempool_new(FALSE, 0));
 
     a.channels = b.channels = 1;
     a.rate = b.rate = 44100;
index 5b26c0f1e5a4f7d1ca5a6406b12aa8562085b68d..5bfc97e08cd18ee199db634605a6b86274c9424c 100644 (file)
@@ -5,6 +5,7 @@
 
 int main(int argc, char *argv[]) {
     pa_volume_t v;
+    pa_cvolume cv;
 
     for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) {
 
@@ -13,6 +14,17 @@ int main(int argc, char *argv[]) {
 
         printf("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i\n",
                v, (v*100)/PA_VOLUME_NORM, dB, f, pa_sw_volume_from_dB(dB), pa_sw_volume_from_linear(f));
+    }
+
+    for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) {
+        char s[PA_CVOLUME_SNPRINT_MAX], t[PA_SW_CVOLUME_SNPRINT_DB_MAX];
+
+        pa_cvolume_set(&cv, 2, v);
+
+        printf("Volume: %3i [%s] [%s]\n",
+               v,
+               pa_cvolume_snprint(s, sizeof(s), &cv),
+               pa_sw_cvolume_snprint_dB(t, sizeof(t), &cv));
 
     }
 
index f2fdede491e4d5577d1019ac436b1e6bbe0667c8..2e6e557586bb2de60a1e230d1428f9e67ca19d6e 100644 (file)
@@ -422,7 +422,7 @@ static void fd_info_unref(fd_info *i) {
     pthread_mutex_lock(&i->mutex);
     assert(i->ref >= 1);
     r = --i->ref;
-        debug(DEBUG_LEVEL_VERBOSE, __FILE__": ref--, now %i\n", i->ref);
+    debug(DEBUG_LEVEL_VERBOSE, __FILE__": ref--, now %i\n", i->ref);
     pthread_mutex_unlock(&i->mutex);
 
     if (r <= 0)
@@ -498,7 +498,6 @@ static void atfork_prepare(void) {
 
     pthread_mutex_lock(&func_mutex);
 
-
     debug(DEBUG_LEVEL_NORMAL, __FILE__": atfork_prepare() exit\n");
 }
 
@@ -550,12 +549,14 @@ static void atfork_child(void) {
         }
 
         if (i->app_fd >= 0) {
-            close(i->app_fd);
+            LOAD_CLOSE_FUNC();
+            _close(i->app_fd);
             i->app_fd = -1;
         }
 
         if (i->thread_fd >= 0) {
-            close(i->thread_fd);
+            LOAD_CLOSE_FUNC();
+            _close(i->thread_fd);
             i->thread_fd = -1;
         }
 
@@ -943,6 +944,10 @@ static int fd_info_copy_data(fd_info *i, int force) {
         api->io_enable(i->io_event, i->io_flags);
     }
 
+    /* So, we emptied the socket now, let's tell dsp_empty_socket()
+     * about this */
+    pa_threaded_mainloop_signal(i->mainloop, 0);
+
     return 0;
 }