summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac6
-rw-r--r--man/pulse-client.conf.5.xml.in19
-rw-r--r--man/pulse-daemon.conf.5.xml.in51
-rw-r--r--man/pulseaudio.1.xml.in2
-rw-r--r--po/POTFILES.in4
-rw-r--r--po/de.po552
-rw-r--r--po/el.po138
-rw-r--r--po/fr.po175
-rw-r--r--po/pl.po90
-rw-r--r--po/pt_BR.po490
-rw-r--r--po/sv.po357
-rw-r--r--src/.gitignore3
-rw-r--r--src/Makefile.am71
-rw-r--r--src/daemon/caps.c5
-rw-r--r--src/daemon/daemon-conf.c36
-rw-r--r--src/daemon/daemon-conf.h1
-rw-r--r--src/daemon/daemon.conf.in3
-rwxr-xr-xsrc/daemon/default.pa.in5
-rw-r--r--src/daemon/main.c8
-rwxr-xr-xsrc/daemon/system.pa.in5
-rw-r--r--src/map-file4
-rw-r--r--src/modules/alsa-util.c24
-rw-r--r--src/modules/alsa-util.h2
l---------src/modules/bluetooth/Makefile1
-rw-r--r--src/modules/bluetooth/ipc.c118
-rw-r--r--src/modules/bluetooth/ipc.h308
-rw-r--r--src/modules/bluetooth/module-bluetooth-device.c922
-rw-r--r--src/modules/bluetooth/module-bluetooth-discover.c543
-rw-r--r--src/modules/bluetooth/module-bluetooth-proximity.c (renamed from src/modules/module-bt-proximity.c)4
-rw-r--r--src/modules/bluetooth/proximity-helper.c (renamed from src/modules/bt-proximity-helper.c)0
-rw-r--r--src/modules/bluetooth/rtp.h76
-rw-r--r--src/modules/bluetooth/sbc.c1411
-rw-r--r--src/modules/bluetooth/sbc.h97
-rw-r--r--src/modules/bluetooth/sbc_math.h72
-rw-r--r--src/modules/bluetooth/sbc_tables.h167
l---------[-rw-r--r--]src/modules/gconf/Makefile14
-rw-r--r--src/modules/gconf/module-gconf.c12
-rw-r--r--src/modules/module-alsa-sink.c101
-rw-r--r--src/modules/module-alsa-source.c105
-rw-r--r--src/modules/module-null-sink.c9
-rw-r--r--src/modules/module-protocol-stub.c2
-rw-r--r--src/modules/module-suspend-on-idle.c2
-rw-r--r--src/modules/module-tunnel.c9
l---------[-rw-r--r--]src/modules/rtp/Makefile14
-rw-r--r--src/modules/rtp/module-rtp-recv.c2
-rw-r--r--src/pulse/channelmap.c13
-rw-r--r--src/pulse/channelmap.h10
-rw-r--r--src/pulse/client-conf.c3
-rw-r--r--src/pulse/client-conf.h1
-rw-r--r--src/pulse/client.conf.in1
-rw-r--r--src/pulse/context.c4
-rw-r--r--src/pulse/introspect.c2
-rw-r--r--src/pulse/sample.c12
-rw-r--r--src/pulse/sample.h11
-rw-r--r--src/pulse/stream.c21
-rw-r--r--src/pulse/volume.c110
-rw-r--r--src/pulse/volume.h44
-rw-r--r--src/pulsecore/conf-parser.c18
-rw-r--r--src/pulsecore/conf-parser.h3
-rw-r--r--src/pulsecore/core-scache.c31
-rw-r--r--src/pulsecore/core-util.c54
-rw-r--r--src/pulsecore/core-util.h13
-rw-r--r--src/pulsecore/core.c8
-rw-r--r--src/pulsecore/core.h2
-rw-r--r--src/pulsecore/flist.h3
-rw-r--r--src/pulsecore/idxset.c2
-rw-r--r--src/pulsecore/log.c3
-rw-r--r--src/pulsecore/macro.h2
-rw-r--r--src/pulsecore/memblock.c36
-rw-r--r--src/pulsecore/memblock.h2
-rw-r--r--src/pulsecore/namereg.c3
-rw-r--r--src/pulsecore/namereg.h2
-rw-r--r--src/pulsecore/prioq.c256
-rw-r--r--src/pulsecore/prioq.h64
-rw-r--r--src/pulsecore/proplist-util.c2
-rw-r--r--src/pulsecore/protocol-native.c6
-rw-r--r--src/pulsecore/protocol-simple.c12
-rw-r--r--src/pulsecore/sample-util.c197
-rw-r--r--src/pulsecore/sconv-s16le.c20
-rw-r--r--src/pulsecore/sconv.c4
-rw-r--r--src/pulsecore/sink-input.c3
-rw-r--r--src/pulsecore/sink.c1
-rw-r--r--src/pulsecore/thread.h3
-rw-r--r--src/pulsecore/time-smoother.c8
-rw-r--r--src/tests/envelope-test.c2
-rw-r--r--src/tests/mcalign-test.c2
-rw-r--r--src/tests/memblock-test.c6
-rw-r--r--src/tests/memblockq-test.c2
-rw-r--r--src/tests/mix-test.c8
-rw-r--r--src/tests/prioq-test.c44
-rw-r--r--src/tests/remix-test.c2
-rw-r--r--src/tests/resampler-test.c2
-rw-r--r--src/tests/voltest.c12
-rw-r--r--src/utils/padsp.c13
94 files changed, 5932 insertions, 1191 deletions
diff --git a/configure.ac b/configure.ac
index 3c3550fb..2b91a006 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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.])
diff --git a/man/pulse-client.conf.5.xml.in b/man/pulse-client.conf.5.xml.in
index ae8de1f8..26e38908 100644
--- a/man/pulse-client.conf.5.xml.in
+++ b/man/pulse-client.conf.5.xml.in
@@ -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">
diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index ed158dfa..a516ee3f 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -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>
@@ -77,6 +77,11 @@ USA.
</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>,
<opt>src-sinc-medium-quality</opt>, <opt>src-sinc-fastest</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>
@@ -282,6 +304,9 @@ USA.
<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>
<option>
@@ -300,6 +325,15 @@ USA.
<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
memory.</p>
@@ -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>
diff --git a/man/pulseaudio.1.xml.in b/man/pulseaudio.1.xml.in
index 0e008c3d..df828242 100644
--- a/man/pulseaudio.1.xml.in
+++ b/man/pulseaudio.1.xml.in
@@ -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>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 6efb1d08..c20340ea 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -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
diff --git a/po/de.po b/po/de.po
index 4fc87068..b587e21c 100644
--- 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 "Kompiliere CFLAGS: %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"
-
diff --git a/po/el.po b/po/el.po
index b664491b..79ccda73 100644
--- 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 ""
diff --git a/po/fr.po b/po/fr.po
index 9cd91bf3..6d35390a 100644
--- 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"
diff --git a/po/pl.po b/po/pl.po
index 4be8e060..5c5b3b4f 100644
--- 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
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 8bf905b0..94494f7f 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -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"
-
diff --git a/po/sv.po b/po/sv.po
index 11f6e13c..772e1552 100644
--- 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"
diff --git a/src/.gitignore b/src/.gitignore
index 543f4e8e..72c38cc6 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -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
diff --git a/src/Makefile.am b/src/Makefile.am
index 1663d66d..f2771980 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -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
diff --git a/src/daemon/caps.c b/src/daemon/caps.c
index f7b6658b..707b5323 100644
--- a/src/daemon/caps.c
+++ b/src/daemon/caps.c
@@ -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
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 77da3f7e..939b25d7 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -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);
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index 309a1428..90329268 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -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 */
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index ea09fe09..c672d420 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -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
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 5f35e3ec..7032038d 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -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
diff --git a/src/daemon/main.c b/src/daemon/main.c
index a9e8ed46..bc8bc63e 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -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;
}
diff --git a/src/daemon/system.pa.in b/src/daemon/system.pa.in
index f6052c4b..27e42815 100755
--- a/src/daemon/system.pa.in
+++ b/src/daemon/system.pa.in
@@ -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
diff --git a/src/map-file b/src/map-file
index 67a5ee36..7211914a 100644
--- a/src/map-file
+++ b/src/map-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;
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c
index c3eb72f5..ffe7795e 100644
--- a/src/modules/alsa-util.c
+++ b/src/modules/alsa-util.c
@@ -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;
-}
diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h
index 7991a107..b66adc13 100644
--- a/src/modules/alsa-util.h
+++ b/src/modules/alsa-util.h
@@ -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
index 00000000..efe5a336
--- /dev/null
+++ b/src/modules/bluetooth/Makefile
@@ -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
index 00000000..98256998
--- /dev/null
+++ b/src/modules/bluetooth/ipc.c
@@ -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
index 00000000..ae85e727
--- /dev/null
+++ b/src/modules/bluetooth/ipc.h
@@ -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
index 00000000..3460fe9a
--- /dev/null
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -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
index 00000000..a33ca648
--- /dev/null
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -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;
+}
diff --git a/src/modules/module-bt-proximity.c b/src/modules/bluetooth/module-bluetooth-proximity.c
index f924c3cb..4cfaaf5b 100644
--- a/src/modules/module-bt-proximity.c
+++ b/src/modules/bluetooth/module-bluetooth-proximity.c
@@ -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/bt-proximity-helper.c b/src/modules/bluetooth/proximity-helper.c
index 3767f01c..3767f01c 100644
--- a/src/modules/bt-proximity-helper.c
+++ b/src/modules/bluetooth/proximity-helper.c
diff --git a/src/modules/bluetooth/rtp.h b/src/modules/bluetooth/rtp.h
new file mode 100644
index 00000000..690bd43a
--- /dev/null
+++ b/src/modules/bluetooth/rtp.h
@@ -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
index 00000000..02a6143d
--- /dev/null
+++ b/src/modules/bluetooth/sbc.c
@@ -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
index 00000000..ab47e329
--- /dev/null
+++ b/src/modules/bluetooth/sbc.h
@@ -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
index 00000000..b3d87a62
--- /dev/null
+++ b/src/modules/bluetooth/sbc_math.h
@@ -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
index 00000000..7ac4e68b
--- /dev/null
+++ b/src/modules/bluetooth/sbc_tables.h
@@ -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) }
+};
diff --git a/src/modules/gconf/Makefile b/src/modules/gconf/Makefile
index 316beb72..efe5a336 100644..120000
--- a/src/modules/gconf/Makefile
+++ b/src/modules/gconf/Makefile
@@ -1,13 +1 @@
-# 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
+../../pulse/Makefile \ No newline at end of file
diff --git a/src/modules/gconf/module-gconf.c b/src/modules/gconf/module-gconf.c
index 6e8ab6ea..845ede50 100644
--- a/src/modules/gconf/module-gconf.c
+++ b/src/modules/gconf/module-gconf.c
@@ -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);
diff --git a/src/modules/module-alsa-sink.c b/src/modules/module-alsa-sink.c
index b8bef935..0e15da3c 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -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 &&
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c
index cb777672..2827ecfe 100644
--- a/src/modules/module-alsa-source.c
+++ b/src/modules/module-alsa-source.c
@@ -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;
diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c
index 9162960f..470c622e 100644
--- a/src/modules/module-null-sink.c
+++ b/src/modules/module-null-sink.c
@@ -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) {
diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c
index 0e98b1c3..aefd4020 100644
--- a/src/modules/module-protocol-stub.c
+++ b/src/modules/module-protocol-stub.c
@@ -148,7 +148,7 @@
# 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"
diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c
index bc7c023c..6cc28ec5 100644
--- a/src/modules/module-suspend-on-idle.c
+++ b/src/modules/module-suspend-on-idle.c
@@ -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;
diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index de3c7274..4bbb11a5 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -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);
diff --git a/src/modules/rtp/Makefile b/src/modules/rtp/Makefile
index 316beb72..efe5a336 100644..120000
--- a/src/modules/rtp/Makefile
+++ b/src/modules/rtp/Makefile
@@ -1,13 +1 @@
-# 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
+../../pulse/Makefile \ No newline at end of file
diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c
index 01637892..e35773cc 100644
--- a/src/modules/rtp/module-rtp-recv.c
+++ b/src/modules/rtp/module-rtp-recv.c
@@ -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);
diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index 37308751..fd313bd3 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -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;
}
diff --git a/src/pulse/channelmap.h b/src/pulse/channelmap.h
index d2dd6f8f..d7d19d79 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -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 */
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c
index 739ef161..58d64642 100644
--- a/src/pulse/client-conf.c
+++ b/src/pulse/client-conf.c
@@ -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) {
diff --git a/src/pulse/client-conf.h b/src/pulse/client-conf.h
index 699279aa..4eac467e 100644
--- a/src/pulse/client-conf.h
+++ b/src/pulse/client-conf.h
@@ -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 */
diff --git a/src/pulse/client.conf.in b/src/pulse/client.conf.in
index 8339d651..579bcc20 100644
--- a/src/pulse/client.conf.in
+++ b/src/pulse/client.conf.in
@@ -30,3 +30,4 @@
; cookie-file =
; disable-shm = no
+; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
diff --git a/src/pulse/context.c b/src/pulse/context.c
index 154e5faf..3145d9c8 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -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);
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c
index 4e362fd8..38091581 100644
--- a/src/pulse/introspect.c
+++ b/src/pulse/introspect.c
@@ -24,6 +24,8 @@
#include <config.h>
#endif
+#include <string.h>
+
#include <pulse/context.h>
#include <pulse/gccmacro.h>
diff --git a/src/pulse/sample.c b/src/pulse/sample.c
index 93da2465..29501595 100644
--- a/src/pulse/sample.c
+++ b/src/pulse/sample.c
@@ -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);
diff --git a/src/pulse/sample.h b/src/pulse/sample.h
index 3f1b2fcf..3c7dd0e7 100644
--- a/src/pulse/sample.h
+++ b/src/pulse/sample.h
@@ -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 */
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index d0c7d67e..00aa1cf9 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -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;
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 15938cbc..99a85f44 100644
--- a/src/pulse/volume.c
+++ b/src/pulse/volume.c
@@ -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;
+}
diff --git a/src/pulse/volume.h b/src/pulse/volume.h
index d612c7f9..75051af5 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -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
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index 6b0e1d56..58ceab91 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -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;
diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h
index 7eb1fae2..a5174fce 100644
--- a/src/pulsecore/conf-parser.h
+++ b/src/pulsecore/conf-parser.h
@@ -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);
diff --git a/src/pulsecore/core-scache.c b/src/pulsecore/core-scache.c
index 814dff59..1d080e11 100644
--- a/src/pulsecore/core-scache.c
+++ b/src/pulsecore/core-scache.c
@@ -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;
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 3e5ea492..dde34d7b 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -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
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index df8ce3f8..fd6ee896 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -35,6 +35,10 @@
#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
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index bd956ae0..5761bbc7 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -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;
}
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index fb4490f2..39559082 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -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);
diff --git a/src/pulsecore/flist.h b/src/pulsecore/flist.h
index 2d8422f9..512dd357 100644
--- a/src/pulsecore/flist.h
+++ b/src/pulsecore/flist.h
@@ -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)); \
} \
diff --git a/src/pulsecore/idxset.c b/src/pulsecore/idxset.c
index 2de64069..24a28db7 100644
--- a/src/pulsecore/idxset.c
+++ b/src/pulsecore/idxset.c
@@ -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) {
diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c
index d7318081..b1de6966 100644
--- a/src/pulsecore/log.c
+++ b/src/pulsecore/log.c
@@ -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);
}
diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h
index fd33b7bb..39e9b587 100644
--- a/src/pulsecore/macro.h
+++ b/src/pulsecore/macro.h
@@ -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); \
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index 6d12acdc..d9e1bf1c 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -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);
diff --git a/src/pulsecore/memblock.h b/src/pulsecore/memblock.h
index efe55b02..b1eab2a9 100644
--- a/src/pulsecore/memblock.h
+++ b/src/pulsecore/memblock.h
@@ -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);
diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
index ad697ed5..ecd8def8 100644
--- a/src/pulsecore/namereg.c
+++ b/src/pulsecore/namereg.c
@@ -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;
diff --git a/src/pulsecore/namereg.h b/src/pulsecore/namereg.h
index 3c1de8e7..f4581006 100644
--- a/src/pulsecore/namereg.h
+++ b/src/pulsecore/namereg.h
@@ -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
index 00000000..693dc517
--- /dev/null
+++ b/src/pulsecore/prioq.c
@@ -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
index 00000000..fd3550b7
--- /dev/null
+++ b/src/pulsecore/prioq.h
@@ -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
diff --git a/src/pulsecore/proplist-util.c b/src/pulsecore/proplist-util.c
index 6005775e..4d505f57 100644
--- a/src/pulsecore/proplist-util.c
+++ b/src/pulsecore/proplist-util.c
@@ -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;
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 6ccee571..778aab57 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -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);
}
diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c
index 65e67737..743bf2ee 100644
--- a/src/pulsecore/protocol-simple.c
+++ b/src/pulsecore/protocol-simple.c
@@ -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;
diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index b4234af5..7b9ac7bc 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -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);
diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c
index 693d529b..159c4655 100644
--- a/src/pulsecore/sconv-s16le.c
+++ b/src/pulsecore/sconv-s16le.c
@@ -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);
}
}
diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c
index 733a46ae..6c4d420e 100644
--- a/src/pulsecore/sconv.c
+++ b/src/pulsecore/sconv.c
@@ -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));
}
}
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 326a7e2c..4f70347f 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -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
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 6fa22dc2..e04fc08a 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -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);
diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h
index 87e850d6..eabe9ba4 100644
--- a/src/pulsecore/thread.h
+++ b/src/pulsecore/thread.h
@@ -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) { \
diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c
index b165f4a8..6a2ffaa6 100644
--- a/src/pulsecore/time-smoother.c
+++ b/src/pulsecore/time-smoother.c
@@ -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) {
diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c
index d71eff1c..4a72f5a3 100644
--- a/src/tests/envelope-test.c
+++ b/src/tests/envelope-test.c
@@ -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);
diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c
index c0665822..92e3e14e 100644
--- a/src/tests/mcalign-test.c
+++ b/src/tests/mcalign-test.c
@@ -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);
diff --git a/src/tests/memblock-test.c b/src/tests/memblock-test.c
index 6da1b1e9..37b5b403 100644
--- a/src/tests/memblock-test.c
+++ b/src/tests/memblock-test.c
@@ -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);
diff --git a/src/tests/memblockq-test.c b/src/tests/memblockq-test.c
index 7bf992a1..c53945b4 100644
--- a/src/tests/memblockq-test.c
+++ b/src/tests/memblockq-test.c
@@ -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);
diff --git a/src/tests/mix-test.c b/src/tests/mix-test.c
index 544121fd..cc21ab03 100644
--- a/src/tests/mix-test.c
+++ b/src/tests/mix-test.c
@@ -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
index 00000000..120b512b
--- /dev/null
+++ b/src/tests/prioq-test.c
@@ -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;
+}
diff --git a/src/tests/remix-test.c b/src/tests/remix-test.c
index 4777c150..3538d7d4 100644
--- a/src/tests/remix-test.c
+++ b/src/tests/remix-test.c
@@ -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++) {
diff --git a/src/tests/resampler-test.c b/src/tests/resampler-test.c
index 6959127b..2d591867 100644
--- a/src/tests/resampler-test.c
+++ b/src/tests/resampler-test.c
@@ -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;
diff --git a/src/tests/voltest.c b/src/tests/voltest.c
index 5b26c0f1..5bfc97e0 100644
--- a/src/tests/voltest.c
+++ b/src/tests/voltest.c
@@ -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));
}
diff --git a/src/utils/padsp.c b/src/utils/padsp.c
index f2fdede4..2e6e5575 100644
--- a/src/utils/padsp.c
+++ b/src/utils/padsp.c
@@ -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;
}