summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am2
-rw-r--r--PROTOCOL26
-rwxr-xr-xbootstrap.sh4
-rw-r--r--configure.ac273
-rw-r--r--doxygen/doxygen.conf.in929
-rw-r--r--libpulse-browse.pc.in9
-rw-r--r--libpulse-mainloop-glib.pc.in9
-rw-r--r--libpulse-simple.pc.in9
-rw-r--r--libpulse.pc.in9
-rw-r--r--m4/.gitignore9
-rw-r--r--m4/attributes.m4258
-rw-r--r--m4/tls.m417
-rw-r--r--man/Makefile.am115
-rw-r--r--man/pacat.1.xml.in6
-rw-r--r--man/pulse-client.conf.5.xml.in19
-rw-r--r--man/pulse-daemon.conf.5.xml.in65
-rw-r--r--man/pulseaudio.1.xml.in2
-rw-r--r--po/LINGUAS5
-rw-r--r--po/POTFILES.in5
-rw-r--r--po/de.po964
-rw-r--r--po/el.po1824
-rw-r--r--po/fr.po2178
-rw-r--r--po/pl.po2113
-rw-r--r--po/pt_BR.po2130
-rw-r--r--po/sv.po1836
-rw-r--r--src/.gitignore4
-rw-r--r--src/Makefile.am928
-rw-r--r--src/daemon/caps.c7
-rw-r--r--src/daemon/cmdline.c27
-rw-r--r--src/daemon/cpulimit.c21
-rw-r--r--src/daemon/daemon-conf.c165
-rw-r--r--src/daemon/daemon-conf.h7
-rw-r--r--src/daemon/daemon.conf.in7
-rwxr-xr-xsrc/daemon/default.pa.in12
-rw-r--r--src/daemon/dumpmodules.c2
-rw-r--r--src/daemon/ltdl-bind-now.c10
-rw-r--r--src/daemon/main.c93
-rwxr-xr-xsrc/daemon/system.pa.in5
-rw-r--r--src/map-file8
-rw-r--r--src/modules/alsa-util.c286
-rw-r--r--src/modules/alsa-util.h7
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.c558
-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
-rw-r--r--src/modules/dbus-util.c8
l---------[-rw-r--r--]src/modules/gconf/Makefile14
-rw-r--r--src/modules/gconf/module-gconf.c20
-rw-r--r--src/modules/module-alsa-sink.c441
-rw-r--r--src/modules/module-alsa-source.c410
-rw-r--r--src/modules/module-combine.c10
-rw-r--r--src/modules/module-detect.c6
-rw-r--r--src/modules/module-device-restore.c17
-rw-r--r--src/modules/module-esound-compat-spawnpid.c2
-rw-r--r--src/modules/module-esound-sink.c20
-rw-r--r--src/modules/module-flat-volume.c224
-rw-r--r--src/modules/module-hal-detect.c12
-rw-r--r--src/modules/module-jack-sink.c10
-rw-r--r--src/modules/module-jack-source.c4
-rw-r--r--src/modules/module-ladspa-sink.c39
-rw-r--r--src/modules/module-lirc.c6
-rw-r--r--src/modules/module-mmkbd-evdev.c6
-rw-r--r--src/modules/module-native-protocol-fd.c13
-rw-r--r--src/modules/module-null-sink.c9
-rw-r--r--src/modules/module-oss.c78
-rw-r--r--src/modules/module-pipe-sink.c6
-rw-r--r--src/modules/module-pipe-source.c6
-rw-r--r--src/modules/module-protocol-stub.c19
-rw-r--r--src/modules/module-raop-discover.c380
-rw-r--r--src/modules/module-raop-sink.c675
-rw-r--r--src/modules/module-remap-sink.c11
-rw-r--r--src/modules/module-sine.c6
-rw-r--r--src/modules/module-stream-restore.c59
-rw-r--r--src/modules/module-suspend-on-idle.c22
-rw-r--r--src/modules/module-tunnel.c47
-rw-r--r--src/modules/module-volume-restore.c2
-rw-r--r--src/modules/module-x11-bell.c2
-rw-r--r--src/modules/module-x11-xsmp.c4
-rw-r--r--src/modules/module-zeroconf-discover.c4
-rw-r--r--src/modules/oss-util.c6
-rw-r--r--src/modules/raop/base64.c126
-rw-r--r--src/modules/raop/base64.h34
-rw-r--r--src/modules/raop/raop_client.c561
-rw-r--r--src/modules/raop/raop_client.h46
l---------[-rw-r--r--]src/modules/rtp/Makefile14
-rw-r--r--src/modules/rtp/headerlist.c186
-rw-r--r--src/modules/rtp/headerlist.h46
-rw-r--r--src/modules/rtp/module-rtp-recv.c20
-rw-r--r--src/modules/rtp/module-rtp-send.c42
-rw-r--r--src/modules/rtp/rtp.c21
-rw-r--r--src/modules/rtp/rtsp_client.c542
-rw-r--r--src/modules/rtp/rtsp_client.h73
-rw-r--r--src/modules/rtp/sap.c28
-rw-r--r--src/modules/rtp/sdp.c8
-rw-r--r--src/pulse/channelmap.c43
-rw-r--r--src/pulse/channelmap.h48
-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.c261
-rw-r--r--src/pulse/def.h781
-rw-r--r--src/pulse/ext-stream-restore.h27
-rw-r--r--src/pulse/gccmacro.h20
-rw-r--r--src/pulse/glib-mainloop.c14
-rw-r--r--src/pulse/internal.h6
-rw-r--r--src/pulse/introspect.c24
-rw-r--r--src/pulse/introspect.h2
-rw-r--r--src/pulse/mainloop-api.c2
-rw-r--r--src/pulse/mainloop-signal.c2
-rw-r--r--src/pulse/mainloop.c93
-rw-r--r--src/pulse/proplist.c2
-rw-r--r--src/pulse/proplist.h16
-rw-r--r--src/pulse/sample.c12
-rw-r--r--src/pulse/sample.h86
-rw-r--r--src/pulse/scache.c3
-rw-r--r--src/pulse/simple.c2
-rw-r--r--src/pulse/stream.c125
-rw-r--r--src/pulse/stream.h2
-rw-r--r--src/pulse/subscribe.c2
-rw-r--r--src/pulse/timeval.c18
-rw-r--r--src/pulse/utf8.c30
-rw-r--r--src/pulse/util.c17
-rw-r--r--src/pulse/volume.c128
-rw-r--r--src/pulse/volume.h49
-rw-r--r--src/pulse/xmalloc.c6
-rw-r--r--src/pulse/xmalloc.h32
-rw-r--r--src/pulsecore/asyncq.c10
-rw-r--r--src/pulsecore/atomic.h46
-rw-r--r--src/pulsecore/authkey.c12
-rw-r--r--src/pulsecore/autoload.c2
-rw-r--r--src/pulsecore/cli-command.c122
-rw-r--r--src/pulsecore/cli-text.c20
-rw-r--r--src/pulsecore/conf-parser.c42
-rw-r--r--src/pulsecore/conf-parser.h4
-rw-r--r--src/pulsecore/core-scache.c35
-rw-r--r--src/pulsecore/core-subscribe.c12
-rw-r--r--src/pulsecore/core-util.c342
-rw-r--r--src/pulsecore/core-util.h54
-rw-r--r--src/pulsecore/core.c12
-rw-r--r--src/pulsecore/core.h5
-rw-r--r--src/pulsecore/endianmacros.h11
-rw-r--r--src/pulsecore/envelope.c22
-rw-r--r--src/pulsecore/fdsem.c54
-rw-r--r--src/pulsecore/flist.h3
-rw-r--r--src/pulsecore/idxset.c7
-rw-r--r--src/pulsecore/ioline.c12
-rw-r--r--src/pulsecore/ipacl.c2
-rw-r--r--src/pulsecore/lock-autospawn.c330
-rw-r--r--src/pulsecore/lock-autospawn.h32
-rw-r--r--src/pulsecore/log.c173
-rw-r--r--src/pulsecore/log.h11
-rw-r--r--src/pulsecore/macro.h14
-rw-r--r--src/pulsecore/memblock.c66
-rw-r--r--src/pulsecore/memblock.h2
-rw-r--r--src/pulsecore/memblockq.c67
-rw-r--r--src/pulsecore/memblockq.h2
-rw-r--r--src/pulsecore/modargs.c2
-rw-r--r--src/pulsecore/module.c8
-rw-r--r--src/pulsecore/namereg.c11
-rw-r--r--src/pulsecore/namereg.h2
-rw-r--r--src/pulsecore/object.h2
-rw-r--r--src/pulsecore/once.c11
-rw-r--r--src/pulsecore/once.h2
-rw-r--r--src/pulsecore/parseaddr.c21
-rw-r--r--src/pulsecore/pdispatch.c2
-rw-r--r--src/pulsecore/pid.c40
-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-esound.c86
-rw-r--r--src/pulsecore/protocol-native.c428
-rw-r--r--src/pulsecore/protocol-simple.c28
-rw-r--r--src/pulsecore/pstream.c14
-rw-r--r--src/pulsecore/resampler.c121
-rw-r--r--src/pulsecore/resampler.h7
-rw-r--r--src/pulsecore/rtclock.h1
-rw-r--r--src/pulsecore/rtpoll.c2
-rw-r--r--src/pulsecore/rtsig.c2
-rw-r--r--src/pulsecore/sample-util.c420
-rw-r--r--src/pulsecore/sample-util.h5
-rw-r--r--src/pulsecore/sconv-s16le.c42
-rw-r--r--src/pulsecore/sconv.c26
-rw-r--r--src/pulsecore/shm.c20
-rw-r--r--src/pulsecore/sink-input.c107
-rw-r--r--src/pulsecore/sink-input.h38
-rw-r--r--src/pulsecore/sink.c90
-rw-r--r--src/pulsecore/sink.h26
-rw-r--r--src/pulsecore/socket-client.c8
-rw-r--r--src/pulsecore/socket-server.c2
-rw-r--r--src/pulsecore/sound-file-stream.c10
-rw-r--r--src/pulsecore/sound-file.c18
-rw-r--r--src/pulsecore/source-output.c53
-rw-r--r--src/pulsecore/source-output.h18
-rw-r--r--src/pulsecore/source.c53
-rw-r--r--src/pulsecore/source.h21
-rw-r--r--src/pulsecore/start-child.c60
-rw-r--r--src/pulsecore/strbuf.c14
-rw-r--r--src/pulsecore/strbuf.h2
-rw-r--r--src/pulsecore/tagstruct.c16
-rw-r--r--src/pulsecore/thread-posix.c9
-rw-r--r--src/pulsecore/thread.h5
-rw-r--r--src/pulsecore/time-smoother.c18
-rw-r--r--src/pulsecore/tokenizer.c2
-rw-r--r--src/pulsecore/x11prop.c4
-rw-r--r--src/pulsecore/x11wrap.c4
-rw-r--r--src/tests/channelmap-test.c6
-rw-r--r--src/tests/cpulimit-test.c4
-rw-r--r--src/tests/envelope-test.c14
-rw-r--r--src/tests/lock-autospawn-test.c109
-rw-r--r--src/tests/mainloop-test.c2
-rw-r--r--src/tests/mcalign-test.c12
-rw-r--r--src/tests/memblock-test.c6
-rw-r--r--src/tests/memblockq-test.c2
-rw-r--r--src/tests/mix-test.c28
-rw-r--r--src/tests/pacat-simple.c4
-rw-r--r--src/tests/parec-simple.c7
-rw-r--r--src/tests/prioq-test.c44
-rw-r--r--src/tests/remix-test.c2
-rw-r--r--src/tests/resampler-test.c22
-rw-r--r--src/tests/rtstutter.c14
-rw-r--r--src/tests/smoother-test.c2
-rw-r--r--src/tests/stripnul.c6
-rw-r--r--src/tests/strlist-test.c2
-rw-r--r--src/tests/sync-playback.c2
-rw-r--r--src/tests/thread-mainloop-test.c2
-rw-r--r--src/tests/voltest.c14
-rw-r--r--src/utils/pacat.c35
-rw-r--r--src/utils/pacmd.c2
-rw-r--r--src/utils/pactl.c18
-rw-r--r--src/utils/padsp.c47
-rw-r--r--src/utils/paplay.c14
240 files changed, 24122 insertions, 4370 deletions
diff --git a/.gitignore b/.gitignore
index 80d9ac71..f869d72d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
ABOUT-NLS
-common/
intltool-extract.in
intltool-merge.in
intltool-update.in
diff --git a/Makefile.am b/Makefile.am
index b5e638bd..b27f9e65 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,7 +58,7 @@ dist-hook:
if test -d .git ; then \
git pull ; \
chmod u+w ${distdir}/ChangeLog || true ; \
- git-changelog.perl > ${distdir}/ChangeLog ; \
+ ( git-changelog.perl || echo "git-changelog.perl failed." ) > ${distdir}/ChangeLog 2>&1 ; \
fi
.PHONY: homepage distcleancheck doxygen
diff --git a/PROTOCOL b/PROTOCOL
index 4885b3d1..80a0c331 100644
--- a/PROTOCOL
+++ b/PROTOCOL
@@ -126,7 +126,7 @@ New field for PA_COMMAND_CREATE_PLAYBACK_STREAM at the end:
Buffer attributes for PA_COMMAND_CREATE_PLAYBACK_STREAM and
PA_COMMAND_CREATE_RECORD_STREAM may now be 0 for default values.
-New filed for PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
+New field for PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR at the end:
adjust_latency (bool)
@@ -140,3 +140,27 @@ new message:
new message:
PA_COMMAND_EXTENSION
+
+PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+ bool volume_set at the end
+
+PA_COMMAND_CREATE_RECORD_STREAM, PA_COMMAND_CREATE_PLAYBACK_STREAM:
+
+ bool early_requests at the end
+
+New field for PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
+PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR at the end:
+
+ early_requests (bool)
+
+
+### v15, implemented by >= 0.9.14
+
+PA_COMMAND_CREATE_PLAYBACK_STREAM
+
+ bool muted at the end
+
+PA_COMMAND_CREATE_PLAYBACK_STREAM, PA_COMMAND_CREATE_RECORD_STREAM:
+
+ bool dont_inhibit_auto_suspend ate the end
diff --git a/bootstrap.sh b/bootstrap.sh
index e5f1ac59..5dfcdf20 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -59,8 +59,8 @@ else
intltoolize --copy --force --automake
"$LIBTOOLIZE" -c --force --ltdl
run_versioned aclocal "$VERSION" -I m4
- run_versioned autoconf 2.59 -Wall
- run_versioned autoheader 2.59
+ run_versioned autoconf 2.62 -Wall
+ run_versioned autoheader 2.62
run_versioned automake "$VERSION" --copy --foreign --add-missing
if test "x$NOCONFIGURE" = "x"; then
diff --git a/configure.ac b/configure.ac
index 8bb3f8ac..95ac9c2e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,27 +24,28 @@ AC_PREREQ(2.62)
m4_define(PA_MAJOR, [0])
m4_define(PA_MINOR, [9])
-m4_define(PA_MICRO, [11])
+m4_define(PA_MICRO, [14])
-AC_INIT([pulseaudio], PA_MAJOR.PA_MINOR.PA_MICRO,[mzchyfrnhqvb (at) 0pointer (dot) net])
+AC_INIT([pulseaudio],[PA_MAJOR.PA_MINOR.PA_MICRO],[mzchyfrnhqvb (at) 0pointer (dot) net])
AC_CONFIG_SRCDIR([src/daemon/main.c])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign 1.10 -Wall])
-AC_SUBST(PA_MAJORMINOR, "PA_MAJOR.PA_MINOR")
+AC_SUBST(PA_MAJORMINOR, PA_MAJOR.PA_MINOR)
+AC_SUBST(PA_MAJORMINORMICRO, PA_MAJOR.PA_MINOR.PA_MICRO)
AC_SUBST(PACKAGE_URL, [http://pulseaudio.org/])
AC_SUBST(PA_API_VERSION, 12)
-AC_SUBST(PA_PROTOCOL_VERSION, 14)
+AC_SUBST(PA_PROTOCOL_VERSION, 15)
# The stable ABI for client applications, for the version info x:y:z
# always will hold y=z
-AC_SUBST(LIBPULSE_VERSION_INFO, [5:0:5])
+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
-AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [0:1:0])
+AC_SUBST(LIBPULSE_SIMPLE_VERSION_INFO, [0:2:0])
# The ABI-stable network browsing interface for client applications,
# for the version info x:y:z always will hold y=z
@@ -52,12 +53,7 @@ AC_SUBST(LIBPULSE_BROWSE_VERSION_INFO, [1:1:1])
# The ABI-stable GLib adapter for client applications, for the version
# info x:y:z always will hold y=z
-AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:3: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, [6:0:0])
+AC_SUBST(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO, [0:4:0])
AC_CANONICAL_HOST
AC_DEFINE_UNQUOTED([CANONICAL_HOST], "$host", [Canonical host string.])
@@ -86,9 +82,10 @@ AC_PROG_MKDIR_P
# CC
AC_PROG_CC
+AC_PROG_CC_C99
AM_PROG_CC_C_O
AC_PROG_GCC_TRADITIONAL
-AC_GNU_SOURCE
+AC_USE_SYSTEM_EXTENSIONS
# M4
@@ -97,37 +94,16 @@ if test "x$M4" = xno ; then
AC_MSG_ERROR([m4 missing])
fi
-# GCC flags
-
-test_gcc_flag() {
- AC_LANG_CONFTEST([int main(int argc, char*argv[]) {}])
- $CC -c conftest.c $CFLAGS -o conftest.o > /dev/null 2> /dev/null
- ret=$?
- rm -f conftest.o
- return $ret
-}
-
-# If using GCC specify some additional parameters
-if test "x$GCC" = "xyes" ; then
-
- # We use gnu99 instead of c99 because many have interpreted the standard
- # in a way that int64_t isn't defined on non-64 bit platforms.
- DESIRED_FLAGS="-std=gnu99 -Wall -W -Wextra -pedantic -pipe -Wformat -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wno-unused-parameter -ffast-math"
-
- for flag in $DESIRED_FLAGS ; do
- AC_MSG_CHECKING([whether $CC accepts $flag])
- if test_gcc_flag $flag ; then
- CFLAGS="$CFLAGS $flag"
- AC_MSG_RESULT([yes])
- else
- AC_MSG_RESULT([no])
- fi
- done
-fi
+dnl Compiler flags
+DESIRED_FLAGS="-Wall -W -Wextra -pedantic -pipe -Wno-long-long -Wvla -Wno-overlength-strings -Wconversion -Wundef -Wformat -Wlogical-op -Wpacked -Wformat-security -Wmissing-include-dirs -Wformat-nonliteral -Wold-style-definition -Wdeclaration-after-statement -Wfloat-equal -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wredundant-decls -Wmissing-noreturn -Wshadow -Wendif-labels -Wpointer-arith -Wcast-align -Wwrite-strings -Wno-unused-parameter -ffast-math"
+
+for flag in $DESIRED_FLAGS ; do
+ CC_CHECK_CFLAGS([$flag], [CFLAGS="$CFLAGS $flag"])
+done
# Native atomic operation support
AC_ARG_ENABLE([atomic-arm-linux-helpers],
- AC_HELP_STRING([--disable-atomic-arm-linux-helpers], [use inline asm or libatomic_ops instead]),
+ AS_HELP_STRING([--disable-atomic-arm-linux-helpers],[use inline asm or libatomic_ops instead]),
[
case "${enableval}" in
yes) atomic_arm_linux_helpers=yes ;;
@@ -138,7 +114,7 @@ AC_ARG_ENABLE([atomic-arm-linux-helpers],
[atomic_arm_linux_helpers=auto])
AC_ARG_ENABLE([atomic-arm-memory-barrier],
- AC_HELP_STRING([--enable-atomic-arm-memory-barrier], [only really needed in SMP arm systems]),
+ AS_HELP_STRING([--enable-atomic-arm-memory-barrier],[only really needed in SMP arm systems]),
[
case "${enableval}" in
yes) AC_DEFINE_UNQUOTED(ATOMIC_ARM_MEMORY_BARRIER_ENABLED, 1, [Enable memory barriers]) ;;
@@ -162,17 +138,18 @@ esac
# If everything else fails use libatomic_ops
need_libatomic_ops=yes
-AC_MSG_CHECKING([whether $CC knows __sync_bool_compare_and_swap()])
-AC_LANG_CONFTEST([int main() { int a = 4; __sync_bool_compare_and_swap(&a, 4, 5); }])
-$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null
-ret=$?
-rm -f conftest.o conftest
-if test $ret -eq 0 ; then
+AC_CACHE_CHECK([whether $CC knows __sync_bool_compare_and_swap()],
+ pulseaudio_cv_sync_bool_compare_and_swap,
+ [AC_LINK_IFELSE(
+ AC_LANG_PROGRAM([], [[int a = 4; __sync_bool_compare_and_swap(&a, 4, 5);]]),
+ [pulseaudio_cv_sync_bool_compare_and_swap=yes],
+ [pulseaudio_cv_sync_bool_compare_and_swap=no])
+ ])
+
+if test "$pulseaudio_cv_sync_bool_compare_and_swap" = "yes" ; then
AC_DEFINE([HAVE_ATOMIC_BUILTINS], 1, [Have __sync_bool_compare_and_swap() and friends.])
- AC_MSG_RESULT([yes])
need_libatomic_ops=no
else
- AC_MSG_RESULT([no])
# HW specific atomic ops stuff
AC_MSG_CHECKING([architecture for native atomic operations])
case $host_cpu in
@@ -188,29 +165,27 @@ else
need_libatomic_ops=no
else
AC_MSG_RESULT([no])
- AC_MSG_CHECKING([compiler support for arm inline asm atomic operations])
- AC_LANG_CONFTEST([[int main()
- {
- volatile int a=0;
- int o=0, n=1, r;
- asm volatile ("ldrex %0, [%1]\n"
- "subs %0, %0, %2\n"
- "strexeq %0, %3, [%1]\n"
- : "=&r" (r)
- : "r" (&a), "Ir" (o), "r" (n)
- : "cc");
- return (a==1 ? 0 : -1);
- }]])
- $CC conftest.c $CFLAGS -o conftest > /dev/null 2>&1
- ret=$?
- rm -f conftest.o conftest
- if test $ret -eq 0 ; then
+ AC_CACHE_CHECK([compiler support for arm inline asm atomic operations],
+ pulseaudio_cv_support_arm_atomic_ops,
+ [AC_COMPILE_IFELSE(
+ AC_LANG_PROGRAM([],
+ [[volatile int a=0;
+ int o=0, n=1, r;
+ asm volatile ("ldrex %0, [%1]\n"
+ "subs %0, %0, %2\n"
+ "strexeq %0, %3, [%1]\n"
+ : "=&r" (r)
+ : "r" (&a), "Ir" (o), "r" (n)
+ : "cc");
+ return (a==1 ? 0 : -1);
+ ]]),
+ [pulseaudio_cv_support_arm_atomic_ops=yes],
+ [pulseaudio_cv_support_arm_atomic_ops=no])
+ ])
+ AS_IF([test "$pulseaudio_cv_support_arm_atomic_ops" = "yes"], [
AC_DEFINE([ATOMIC_ARM_INLINE_ASM], 1, [Have ARMv6 instructions.])
- AC_MSG_RESULT([yes])
need_libatomic_ops=no
- else
- AC_MSG_RESULT([no])
- fi
+ ])
fi
;;
*)
@@ -219,29 +194,19 @@ else
esac
fi
-AC_MSG_CHECKING([whether $CC knows __thread])
-AC_LANG_CONFTEST([static __thread int a = 6; int main() { a = 5; }])
-$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null
-ret=$?
-rm -f conftest.o conftest
-if test $ret -eq 0 ; then
- AC_DEFINE([HAVE_TLS_BUILTIN], 1, [Have __thread().])
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
+CC_CHECK_TLS
+
+AC_CACHE_CHECK([whether $CC knows _Bool],
+ pulseaudio_cv__Bool,
+ [AC_COMPILE_IFELSE(
+ AC_LANG_PROGRAM([], [[_Bool b;]]),
+ [pulseaudio_cv__Bool=yes],
+ [pulseaudio_cv__Bool=no])
+ ])
-AC_MSG_CHECKING([whether $CC knows _Bool])
-AC_LANG_CONFTEST([int main() { _Bool b; }])
-$CC conftest.c $CFLAGS -o conftest > /dev/null 2> /dev/null
-ret=$?
-rm -f conftest.o conftest
-if test $ret -eq 0 ; then
+AS_IF([test "$pulseaudio_cv__Bool" = "yes"], [
AC_DEFINE([HAVE_STD_BOOL], 1, [Have _Bool.])
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
+ ])
#### libtool stuff ####
LT_CONFIG_LTDL_DIR([libltdl])
@@ -307,6 +272,8 @@ AC_CHECK_HEADERS([windows.h winsock2.h ws2tcpip.h])
AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([byteswap.h])
AC_CHECK_HEADERS([sys/syscall.h])
+AC_CHECK_HEADERS([sys/eventfd.h])
+AC_CHECK_HEADERS([execinfo.h])
#### Typdefs, structures, etc. ####
@@ -395,20 +362,29 @@ AC_CHECK_FUNCS([setresuid setresgid setreuid setregid seteuid setegid ppoll strs
AC_FUNC_ALLOCA
-AC_MSG_CHECKING([for PTHREAD_PRIO_INHERIT])
-AC_LANG_CONFTEST([AC_LANG_SOURCE([[
-#include <pthread.h>
-int main() { int i = PTHREAD_PRIO_INHERIT; }]])])
-$PTHREAD_CC conftest.c $PTHREAD_CFLAGS $CFLAGS $PTHREAD_LIBS -o conftest > /dev/null 2> /dev/null
-ret=$?
-rm -f conftest.o conftest
-
-if test $ret -eq 0 ; then
+AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
+ pulseaudio_cv_PTHREAD_PRIO_INHERIT,
+ [save_CC=$CC; CC=$PTHREAD_CC
+ save_CFLAGS=$CFLAGS; CFLAGS=$PTHREAD_CFLAGS
+ save_LIBS=$LIBS; LIBS=$PTHREAD_LIBS
+ AC_LINK_IFELSE(
+ AC_LANG_PROGRAM(
+ [[
+ #include <pthread.h>
+ ]],
+ [[int i = PTHREAD_PRIO_INHERIT;]]),
+ [pulseaudio_cv_PTHREAD_PRIO_INHERIT=yes],
+ [pulseaudio_cv_PTHREAD_PRIO_INHERIT=no])
+ CC=$save_CC
+ CFLAGS=$save_CFLAGS
+ LIBS=$save_LIBS
+ ])
+
+AS_IF([test "$pulseaudio_cv_PTHREAD_PRIO_INHERIT" = "yes"], [
AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])
- AC_MSG_RESULT([yes])
-else
- AC_MSG_RESULT([no])
-fi
+ ])
+
+AC_DEFINE_UNQUOTED(PA_CFLAGS,"$CFLAGS", [The CFLAGS used during compilation])
#### Large File-Support (LFS) ####
@@ -456,7 +432,7 @@ CAP_LIBS=''
AC_ARG_WITH(
[caps],
- AC_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.]))
+ AS_HELP_STRING([--without-caps],[Omit support for POSIX capabilities.]))
if test "x${with_caps}" != "xno"; then
AC_SEARCH_LIBS([cap_init], [cap], [], [
@@ -469,6 +445,10 @@ if test "x${with_caps}" != "xno"; then
fi])
fi
+#### Valgrind (optional) ####
+
+AC_CHECK_HEADERS([valgrind/memcheck.h])
+
#### pkg-config ####
# Check for pkg-config manually first, as if its not installed the
@@ -511,7 +491,7 @@ fi
#### Libsamplerate support (optional) ####
AC_ARG_ENABLE([samplerate],
- AC_HELP_STRING([--disable-samplerate], [Disable optional libsamplerate support]),
+ AS_HELP_STRING([--disable-samplerate],[Disable optional libsamplerate support]),
[
case "${enableval}" in
yes) samplerate=yes ;;
@@ -546,7 +526,7 @@ AM_CONDITIONAL([HAVE_LIBSAMPLERATE], [test "x$HAVE_LIBSAMPLERATE" = x1])
#### OSS support (optional) ####
AC_ARG_ENABLE([oss],
- AC_HELP_STRING([--disable-oss], [Disable optional OSS support]),
+ AS_HELP_STRING([--disable-oss],[Disable optional OSS support]),
[
case "${enableval}" in
yes) oss=yes ;;
@@ -579,7 +559,7 @@ AM_CONDITIONAL([HAVE_OSS], [test "x$HAVE_OSS" = x1])
#### ALSA support (optional) ####
AC_ARG_ENABLE([alsa],
- AC_HELP_STRING([--disable-alsa], [Disable optional ALSA support]),
+ AS_HELP_STRING([--disable-alsa],[Disable optional ALSA support]),
[
case "${enableval}" in
yes) alsa=yes ;;
@@ -613,7 +593,7 @@ AM_CONDITIONAL([HAVE_ALSA], [test "x$HAVE_ALSA" = x1])
#### Solaris audio support (optional) ####
AC_ARG_ENABLE([solaris],
- AC_HELP_STRING([--disable-solaris], [Disable optional Solaris audio support]),
+ AS_HELP_STRING([--disable-solaris],[Disable optional Solaris audio support]),
[
case "${enableval}" in
yes) solaris=yes ;;
@@ -645,7 +625,7 @@ AM_CONDITIONAL([HAVE_SOLARIS], [test "x$HAVE_SOLARIS" = x1])
#### GLib 2 support (optional) ####
AC_ARG_ENABLE([glib2],
- AC_HELP_STRING([--disable-glib2], [Disable optional GLib 2 support]),
+ AS_HELP_STRING([--disable-glib2],[Disable optional GLib 2 support]),
[
case "${enableval}" in
yes) glib2=yes ;;
@@ -676,7 +656,7 @@ AM_CONDITIONAL([HAVE_GLIB20], [test "x$HAVE_GLIB20" = x1])
#### GConf support (optional) ####
AC_ARG_ENABLE([gconf],
- AC_HELP_STRING([--disable-gconf], [Disable optional GConf support]),
+ AS_HELP_STRING([--disable-gconf],[Disable optional GConf support]),
[
case "${enableval}" in
yes) gconf=yes ;;
@@ -707,7 +687,7 @@ AM_CONDITIONAL([HAVE_GCONF], [test "x$HAVE_GCONF" = x1])
#### Avahi support (optional) ####
AC_ARG_ENABLE([avahi],
- AC_HELP_STRING([--disable-avahi], [Disable optional Avahi support]),
+ AS_HELP_STRING([--disable-avahi],[Disable optional Avahi support]),
[
case "${enableval}" in
yes) avahi=yes ;;
@@ -744,7 +724,7 @@ AC_SUBST(LIBOIL_LIBS)
### JACK (optional) ####
AC_ARG_ENABLE([jack],
- AC_HELP_STRING([--disable-jack], [Disable optional JACK support]),
+ AS_HELP_STRING([--disable-jack],[Disable optional JACK support]),
[
case "${enableval}" in
yes) jack=yes ;;
@@ -775,7 +755,7 @@ AM_CONDITIONAL([HAVE_JACK], [test "x$HAVE_JACK" = x1])
#### Async DNS support (optional) ####
AC_ARG_ENABLE([asyncns],
- AC_HELP_STRING([--disable-asyncns], [Disable optional Async DNS support]),
+ AS_HELP_STRING([--disable-asyncns],[Disable optional Async DNS support]),
[
case "${enableval}" in
yes) asyncns=yes ;;
@@ -810,7 +790,7 @@ fi
#### TCP wrappers (optional) ####
AC_ARG_ENABLE([tcpwrap],
- AC_HELP_STRING([--disable-tcpwrap], [Disable optional TCP wrappers support]),
+ AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]),
[
case "${enableval}" in
yes) tcpwrap=yes ;;
@@ -834,7 +814,7 @@ AC_SUBST(LIBWRAP_LIBS)
#### LIRC support (optional) ####
AC_ARG_ENABLE([lirc],
- AC_HELP_STRING([--disable-lirc], [Disable optional LIRC support]),
+ AS_HELP_STRING([--disable-lirc],[Disable optional LIRC support]),
[
case "${enableval}" in
yes) lirc=yes ;;
@@ -860,7 +840,7 @@ AM_CONDITIONAL([HAVE_LIRC], [test "x$HAVE_LIRC" = x1])
#### HAL support (optional) ####
AC_ARG_ENABLE([hal],
- AC_HELP_STRING([--disable-hal], [Disable optional HAL support]),
+ AS_HELP_STRING([--disable-hal],[Disable optional HAL support]),
[
case "${enableval}" in
yes) hal=yes ;;
@@ -890,7 +870,7 @@ AM_CONDITIONAL([HAVE_HAL], [test "x$HAVE_HAL" = x1])
#### BlueZ support (optional) ####
AC_ARG_ENABLE([bluez],
- AC_HELP_STRING([--disable-bluez], [Disable optional BlueZ support]),
+ AS_HELP_STRING([--disable-bluez],[Disable optional BlueZ support]),
[
case "${enableval}" in
yes) bluez=yes ;;
@@ -920,7 +900,7 @@ AM_CONDITIONAL([HAVE_BLUEZ], [test "x$HAVE_BLUEZ" = x1])
#### D-Bus support (optional) ####
AC_ARG_ENABLE([dbus],
- AC_HELP_STRING([--disable-dbus], [Disable optional D-Bus support]),
+ AS_HELP_STRING([--disable-dbus],[Disable optional D-Bus support]),
[
case "${enableval}" in
yes) dbus=yes ;;
@@ -963,7 +943,7 @@ AM_CONDITIONAL([HAVE_DBUS], [test "x$HAVE_DBUS" = x1])
#### PolicyKit support (optional) ####
AC_ARG_ENABLE([polkit],
- AC_HELP_STRING([--disable-polkit], [Disable optional PolicyKit support]),
+ AS_HELP_STRING([--disable-polkit],[Disable optional PolicyKit support]),
[
case "${enableval}" in
yes) polkit=yes ;;
@@ -997,6 +977,41 @@ AC_SUBST(POLKIT_LIBS)
AC_SUBST(HAVE_POLKIT)
AM_CONDITIONAL([HAVE_POLKIT], [test "x$HAVE_POLKIT" = x1])
+#### OpenSSL support (optional) ####
+
+AC_ARG_ENABLE([openssl],
+ AC_HELP_STRING([--disable-openssl], [Disable OpenSSL support (used for Airtunes/RAOP)]),
+ [
+ case "${enableval}" in
+ yes) openssl=yes ;;
+ no) openssl=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --disable-openssl) ;;
+ esac
+ ],
+ [openssl=auto])
+
+if test "x${openssl}" != xno ; then
+
+ PKG_CHECK_MODULES(OPENSSL, [ openssl > 0.9 ],
+ [
+ HAVE_OPENSSL=1
+ AC_DEFINE([HAVE_OPENSSL], 1, [Have OpenSSL])
+ ],
+ [
+ HAVE_OPENSSL=0
+ if test "x$openssl" = xyes ; then
+ AC_MSG_ERROR([*** OpenSSL support not found])
+ fi
+ ])
+else
+ HAVE_OPENSSL=0
+fi
+
+AC_SUBST(OPENSSL_CFLAGS)
+AC_SUBST(OPENSSL_LIBS)
+AC_SUBST(HAVE_OPENSSL)
+AM_CONDITIONAL([HAVE_OPENSSL], [test "x$HAVE_OPENSSL" = x1])
+
### Build and Install man pages ###
AC_ARG_ENABLE(manpages,
AS_HELP_STRING([--disable-manpages],[Disable building and installation of man pages]),
@@ -1076,13 +1091,13 @@ AC_SUBST(PA_SYSTEM_STATE_PATH)
AC_ARG_ENABLE(
[static-bins],
- AC_HELP_STRING([--enable-static-bins],[Statically link executables.]),
+ AS_HELP_STRING([--enable-static-bins],[Statically link executables.]),
[STATIC_BINS=1], [STATIC_BINS=0])
AM_CONDITIONAL([STATIC_BINS], [test "x$STATIC_BINS" = "x1"])
AC_ARG_WITH(
[preopen-mods],
- AC_HELP_STRING([--with-preopen-mods],[Modules to preopen in daemon (default: all).]),
+ AS_HELP_STRING([--with-preopen-mods],[Modules to preopen in daemon (default: all).]),
[PREOPEN_MODS=$withval], [PREOPEN_MODS="all"])
AM_CONDITIONAL([PREOPEN_MODS], [test "x$PREOPEN_MODS" != "xall"])
if test "x$PREOPEN_MODS" != "xall" ; then
@@ -1096,14 +1111,14 @@ fi
AC_ARG_WITH(
[module-dir],
- AC_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINOR}/modules/]),
- [modlibexecdir=$withval], [modlibexecdir="${libdir}/pulse-${PA_MAJORMINOR}/modules/"])
+ AS_HELP_STRING([--with-module-dir],[Directory where to install the modules to (defaults to ${libdir}/pulse-${PA_MAJORMINORMICRO}/modules/]),
+ [modlibexecdir=$withval], [modlibexecdir="${libdir}/pulse-${PA_MAJORMINORMICRO}/modules/"])
AC_SUBST(modlibexecdir)
AC_ARG_ENABLE(
[force-preopen],
- AC_HELP_STRING([--enable-force-preopen],[Preopen modules, even when dlopen() is supported.]),
+ AS_HELP_STRING([--enable-force-preopen],[Preopen modules, even when dlopen() is supported.]),
[FORCE_PREOPEN=1], [FORCE_PREOPEN=0])
AM_CONDITIONAL([FORCE_PREOPEN], [test "x$FORCE_PREOPEN" = "x1"])
@@ -1199,6 +1214,11 @@ if test "x${HAVE_POLKIT}" = "x1" ; then
ENABLE_POLKIT=yes
fi
+ENABLE_OPENSSL=no
+if test "x${HAVE_OPENSSL}" = "x1" ; then
+ ENABLE_OPENSSL=yes
+fi
+
ENABLE_PER_USER_ESOUND_SOCKET=no
if test "x$per_user_esound_socket" = "x1" ; then
ENABLE_PER_USER_ESOUND_SOCKET=yes
@@ -1230,6 +1250,7 @@ echo "
Enable TCP Wrappers: ${ENABLE_TCPWRAP}
Enable libsamplerate: ${ENABLE_LIBSAMPLERATE}
Enable PolicyKit: ${ENABLE_POLKIT}
+ Enable OpenSSL (for Airtunes): ${ENABLE_OPENSSL}
System User: ${PA_SYSTEM_USER}
System Group: ${PA_SYSTEM_GROUP}
Realtime Group: ${PA_REALTIME_GROUP}
diff --git a/doxygen/doxygen.conf.in b/doxygen/doxygen.conf.in
index 7ad5d2f3..6c2021ce 100644
--- a/doxygen/doxygen.conf.in
+++ b/doxygen/doxygen.conf.in
@@ -14,191 +14,191 @@
# Project related configuration options
#---------------------------------------------------------------------------
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.
PROJECT_NAME = PulseAudio
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = @PACKAGE_VERSION@
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
-OUTPUT_DIRECTORY =
+OUTPUT_DIRECTORY =
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of source
-# files, where putting all generated files in the same directory would otherwise
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of source
+# files, where putting all generated files in the same directory would otherwise
# cause performance problems for the file system.
CREATE_SUBDIRS = NO
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
# Swedish, and Ukrainian.
OUTPUT_LANGUAGE = English
-# This tag can be used to specify the encoding used in the generated output.
-# The encoding is not always determined by the language that is chosen,
-# but also whether or not the output is meant for Windows or non-Windows users.
-# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
-# forces the Windows encoding (this is the default for the Windows binary),
-# whereas setting the tag to NO uses a Unix-style encoding (the default for
+# This tag can be used to specify the encoding used in the generated output.
+# The encoding is not always determined by the language that is chosen,
+# but also whether or not the output is meant for Windows or non-Windows users.
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES
+# forces the Windows encoding (this is the default for the Windows binary),
+# whereas setting the tag to NO uses a Unix-style encoding (the default for
# all platforms other than Windows).
USE_WINDOWS_ENCODING = NO
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
# Set to NO to disable this.
BRIEF_MEMBER_DESC = YES
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = YES
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is used
-# as the annotated text. Otherwise, the brief description is used as-is. If left
-# blank, the following values are used ("$name" is automatically replaced with the
-# name of the entity): "The $name class" "The $name widget" "The $name file"
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is used
+# as the annotated text. Otherwise, the brief description is used as-is. If left
+# blank, the following values are used ("$name" is automatically replaced with the
+# name of the entity): "The $name class" "The $name widget" "The $name file"
# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
-ABBREVIATE_BRIEF =
+ABBREVIATE_BRIEF =
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = NO
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
-# members of a class in the documentation of that class as if those members were
-# ordinary class members. Constructors, destructors and assignment operators of
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited
+# members of a class in the documentation of that class as if those members were
+# ordinary class members. Constructors, destructors and assignment operators of
# the base classes will not be shown.
INLINE_INHERITED_MEMB = NO
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
# to NO the shortest path that makes the file name unique will be used.
FULL_PATH_NAMES = NO
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
# path to strip.
-STRIP_FROM_PATH =
+STRIP_FROM_PATH =
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
# are normally passed to the compiler using the -I flag.
-STRIP_FROM_INC_PATH =
+STRIP_FROM_INC_PATH =
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like the Qt-style comments (thus requiring an
# explicit @brief command for a brief description.
JAVADOC_AUTOBRIEF = YES
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
# description. Set this tag to YES if you prefer the old behaviour instead.
MULTILINE_CPP_IS_BRIEF = NO
-# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
# will output the detailed description near the top, like JavaDoc.
-# If set to NO, the detailed description appears after the member
+# If set to NO, the detailed description appears after the member
# documentation.
DETAILS_AT_TOP = NO
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
# re-implements.
INHERIT_DOCS = YES
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
DISTRIBUTE_GROUP_DOC = NO
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
# Doxygen uses this value to replace tabs by spaces in code fragments.
TAB_SIZE = 4
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
# You can put \n's in the value part of an alias to insert newlines.
-ALIASES =
+ALIASES =
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
# of all members will be omitted, etc.
OPTIMIZE_OUTPUT_FOR_C = YES
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
-# only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources
+# only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
# will look different, etc.
OPTIMIZE_OUTPUT_JAVA = NO
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
# the \nosubgrouping command.
SUBGROUPING = YES
@@ -207,162 +207,162 @@ SUBGROUPING = YES
# Build related configuration options
#---------------------------------------------------------------------------
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
EXTRACT_ALL = YES
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
# will be included in the documentation.
EXTRACT_PRIVATE = NO
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
# If set to NO only classes defined in header files are included.
EXTRACT_LOCAL_CLASSES = YES
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
# If set to NO (the default) only methods in the interface are included.
EXTRACT_LOCAL_METHODS = NO
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = NO
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
# overviews. This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_CLASSES = NO
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
# documentation.
HIDE_FRIEND_COMPOUNDS = NO
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
# function's detailed documentation block.
HIDE_IN_BODY_DOCS = NO
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
# Set it to YES to include the internal documentation.
INTERNAL_DOCS = NO
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
CASE_SENSE_NAMES = YES
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
# documentation. If set to YES the scope will be hidden.
HIDE_SCOPE_NAMES = NO
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
# of that file.
SHOW_INCLUDE_FILES = NO
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
# is inserted in the documentation for inline members.
INLINE_INFO = YES
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
# declaration order.
SORT_MEMBER_DOCS = YES
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
# declaration order.
SORT_BRIEF_DOCS = NO
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
+# Note: This option applies only to the class list, not to the
# alphabetical list.
SORT_BY_SCOPE_NAME = NO
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
# commands in the documentation.
GENERATE_TODOLIST = NO
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
# commands in the documentation.
GENERATE_TESTLIST = NO
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
# commands in the documentation.
GENERATE_BUGLIST = NO
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
# \deprecated commands in the documentation.
GENERATE_DEPRECATEDLIST= NO
-# The ENABLED_SECTIONS tag can be used to enable conditional
+# The ENABLED_SECTIONS tag can be used to enable conditional
# documentation sections, marked by \if sectionname ... \endif.
-ENABLED_SECTIONS =
+ENABLED_SECTIONS =
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
# command in the documentation regardless of this setting.
MAX_INITIALIZER_LINES = 30
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
# list will mention the files that were used to generate the documentation.
SHOW_USED_FILES = YES
@@ -371,133 +371,133 @@ SHOW_USED_FILES = YES
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
-# The QUIET tag can be used to turn on/off the messages that are generated
+# The QUIET tag can be used to turn on/off the messages that are generated
# by doxygen. Possible values are YES and NO. If left blank NO is used.
QUIET = NO
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
# NO is used.
WARNINGS = YES
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
# automatically be disabled.
WARN_IF_UNDOCUMENTED = YES
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
# don't exist or using markup commands wrongly.
WARN_IF_DOC_ERROR = YES
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
# warning originated and the warning text.
WARN_FORMAT = "$file:$line: $text"
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
# to stderr.
-WARN_LOGFILE =
+WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../src/pulse/context.h ../src/pulse/stream.h ../src/pulse/pulseaudio.h ../src/pulse/sample.h ../src/pulse/def.h ../src/pulse/subscribe.h ../src/pulse/introspect.h ../src/pulse/scache.h ../src/pulse/mainloop-api.h ../src/pulse/glib-mainloop.h ../src/pulse/mainloop.h ../src/pulse/mainloop-signal.h ../src/pulse/error.h ../src/pulse/operation.h ../src/pulse/simple.h ../src/pulse/version.h ../src/pulse/volume.h ../src/pulse/channelmap.h ../src/pulse/thread-mainloop.h ../src/pulse/xmalloc.h ../src/pulse/utf8.h ../src/pulse/util.h ../src/pulse/timeval.h ../src/pulse/proplist.h ../src/pulse/gccmacro.h
+INPUT = ../src/pulse/context.h ../src/pulse/stream.h ../src/pulse/pulseaudio.h ../src/pulse/sample.h ../src/pulse/def.h ../src/pulse/subscribe.h ../src/pulse/introspect.h ../src/pulse/scache.h ../src/pulse/mainloop-api.h ../src/pulse/glib-mainloop.h ../src/pulse/mainloop.h ../src/pulse/mainloop-signal.h ../src/pulse/error.h ../src/pulse/operation.h ../src/pulse/simple.h ../src/pulse/version.h ../src/pulse/volume.h ../src/pulse/channelmap.h ../src/pulse/thread-mainloop.h ../src/pulse/xmalloc.h ../src/pulse/utf8.h ../src/pulse/util.h ../src/pulse/timeval.h ../src/pulse/proplist.h ../src/pulse/gccmacro.h ../src/pulse/ext-stream-restore.h
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
-FILE_PATTERNS =
+FILE_PATTERNS =
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
# If left blank NO is used.
RECURSIVE = NO
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
-EXCLUDE =
+EXCLUDE =
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories
# that are symbolic links (a Unix filesystem feature) are excluded from the input.
EXCLUDE_SYMLINKS = NO
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
-EXCLUDE_PATTERNS =
+EXCLUDE_PATTERNS =
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = ../src/utils ../src/tests
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
# blank all files are included.
-EXAMPLE_PATTERNS =
+EXAMPLE_PATTERNS =
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
# Possible values are YES and NO. If left blank NO is used.
EXAMPLE_RECURSIVE = NO
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
# the \image command).
-IMAGE_PATH =
+IMAGE_PATH =
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
# ignored.
-INPUT_FILTER =
+INPUT_FILTER =
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
# is applied to all files.
-FILTER_PATTERNS =
+FILTER_PATTERNS =
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
# files to browse (i.e. when SOURCE_BROWSER is set to YES).
FILTER_SOURCE_FILES = NO
@@ -506,38 +506,38 @@ FILTER_SOURCE_FILES = NO
# configuration options related to source browsing
#---------------------------------------------------------------------------
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
# VERBATIM_HEADERS is set to NO.
SOURCE_BROWSER = NO
-# Setting the INLINE_SOURCES tag to YES will include the body
+# Setting the INLINE_SOURCES tag to YES will include the body
# of functions and classes directly in the documentation.
INLINE_SOURCES = NO
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
# fragments. Normal C and C++ comments will always remain visible.
STRIP_CODE_COMMENTS = YES
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
# functions referencing it will be listed.
REFERENCED_BY_RELATION = YES
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
# called/used by that function will be listed.
REFERENCES_RELATION = YES
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
# which an include is specified. Set to NO to disable this.
VERBATIM_HEADERS = YES
@@ -546,21 +546,21 @@ VERBATIM_HEADERS = YES
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
# contains a lot of classes, structs, unions or interfaces.
ALPHABETICAL_INDEX = YES
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
# in which this list will be split (can be a number in the range [1..20])
COLS_IN_ALPHA_INDEX = 5
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
# should be ignored while generating the index headers.
IGNORE_PREFIX = pa_ PA_
@@ -569,110 +569,110 @@ IGNORE_PREFIX = pa_ PA_
# configuration options related to the HTML output
#---------------------------------------------------------------------------
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
# generate HTML output.
GENERATE_HTML = YES
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
HTML_OUTPUT = html
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
# doxygen will generate files with .html extension.
HTML_FILE_EXTENSION = .html
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
# standard header.
-HTML_HEADER =
+HTML_HEADER =
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
# standard footer.
-HTML_FOOTER =
+HTML_FOOTER =
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
# stylesheet in the HTML output directory as well, or it will be erased!
-HTML_STYLESHEET =
+HTML_STYLESHEET =
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
# of the generated HTML documentation.
GENERATE_HTMLHELP = NO
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
# written to the html output directory.
-CHM_FILE =
+CHM_FILE =
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
# the HTML help compiler on the generated index.hhp.
-HHC_LOCATION =
+HHC_LOCATION =
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
# it should be included in the master .chm file (NO).
GENERATE_CHI = NO
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
# normal table of contents (NO) in the .chm file.
BINARY_TOC = NO
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
# to the contents of the HTML help documentation and to the tree view.
TOC_EXPAND = NO
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
# the value YES disables it.
DISABLE_INDEX = NO
-# This tag can be used to set the number of enum values (range [1..20])
+# This tag can be used to set the number of enum values (range [1..20])
# that doxygen will group on one line in the generated HTML documentation.
ENUM_VALUES_PER_LINE = 1
# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
# probably better off using the HTML help feature.
GENERATE_TREEVIEW = YES
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
# is shown.
TREEVIEW_WIDTH = 250
@@ -681,74 +681,74 @@ TREEVIEW_WIDTH = 250
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
# generate Latex output.
GENERATE_LATEX = NO
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `latex' will be used as the default path.
LATEX_OUTPUT = latex
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked. If left blank `latex' will be used as the default command name.
LATEX_CMD_NAME = latex
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
# default command name.
MAKEINDEX_CMD_NAME = makeindex
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_LATEX = NO
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
PAPER_TYPE = a4wide
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
# packages that should be included in the LaTeX output.
-EXTRA_PACKAGES =
+EXTRA_PACKAGES =
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
# standard header. Notice: only use this tag if you know what you are doing!
-LATEX_HEADER =
+LATEX_HEADER =
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
# This makes the output suitable for online browsing using a pdf viewer.
PDF_HYPERLINKS = NO
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
# higher quality PDF documentation.
USE_PDFLATEX = NO
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
# This option is also used when generating formulas in HTML.
LATEX_BATCHMODE = NO
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
# in the output.
LATEX_HIDE_INDICES = NO
@@ -757,68 +757,68 @@ LATEX_HIDE_INDICES = NO
# configuration options related to the RTF output
#---------------------------------------------------------------------------
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
GENERATE_RTF = NO
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `rtf' will be used as the default path.
RTF_OUTPUT = rtf
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
# save some trees in general.
COMPACT_RTF = NO
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
# Note: wordpad (write) and others do not support links.
RTF_HYPERLINKS = NO
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
# replacements, missing definitions are set to their default value.
-RTF_STYLESHEET_FILE =
+RTF_STYLESHEET_FILE =
-# Set optional variables used in the generation of an rtf document.
+# Set optional variables used in the generation of an rtf document.
# Syntax is similar to doxygen's config file.
-RTF_EXTENSIONS_FILE =
+RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
GENERATE_MAN = NO
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `man' will be used as the default path.
MAN_OUTPUT = man
-# The MAN_EXTENSION tag determines the extension that is added to
+# The MAN_EXTENSION tag determines the extension that is added to
# the generated man pages (default is the subroutine's section .3)
MAN_EXTENSION = .3
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
# would be unable to find the correct page. The default is NO.
MAN_LINKS = NO
@@ -827,33 +827,33 @@ MAN_LINKS = NO
# configuration options related to the XML output
#---------------------------------------------------------------------------
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
# the code including all documentation.
GENERATE_XML = NO
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `xml' will be used as the default path.
XML_OUTPUT = xml
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
# syntax of the XML files.
-XML_SCHEMA =
+XML_SCHEMA =
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
# syntax of the XML files.
-XML_DTD =
+XML_DTD =
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
# enabling this will significantly increase the size of the XML output.
XML_PROGRAMLISTING = YES
@@ -862,10 +862,10 @@ XML_PROGRAMLISTING = YES
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
# and incomplete at the moment.
GENERATE_AUTOGEN_DEF = NO
@@ -874,283 +874,282 @@ GENERATE_AUTOGEN_DEF = NO
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
# moment.
GENERATE_PERLMOD = NO
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
# to generate PDF and DVI output from the Perl module output.
PERLMOD_LATEX = NO
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
# and Perl will parse it just the same.
PERLMOD_PRETTY = YES
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
# Makefile don't overwrite each other's variables.
-PERLMOD_MAKEVAR_PREFIX =
+PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
# files.
ENABLE_PREPROCESSING = YES
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
MACRO_EXPANSION = YES
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
EXPAND_ONLY_PREDEF = YES
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
SEARCH_INCLUDES = YES
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
# the preprocessor.
-INCLUDE_PATH =
+INCLUDE_PATH =
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
# be used.
-INCLUDE_FILE_PATTERNS =
+INCLUDE_FILE_PATTERNS =
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
# omitted =1 is assumed.
PREDEFINED = PA_C_DECL_BEGIN= PA_C_DECL_END=
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
#EXPAND_AS_DEFINED = PA_C_DECL_BEGIN, PA_C_DECL_END
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse the
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse the
# parser if not removed.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration::additions related to external references
#---------------------------------------------------------------------------
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
# does not have to be run to correct the links.
# Note that each tag file must have a unique name
# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
+# If a tag file is not located in the directory in which doxygen
# is run, you must also specify the path to the tagfile here.
-TAGFILES =
+TAGFILES =
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
# a tag file that is based on the input files it reads.
-GENERATE_TAGFILE =
+GENERATE_TAGFILE =
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
# will be listed.
ALLEXTERNALS = NO
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
# be listed.
EXTERNAL_GROUPS = YES
-# The PERL_PATH should be the absolute path and name of the perl script
+# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of `which perl').
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# Configuration options related to the dot tool
#---------------------------------------------------------------------------
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
-# super classes. Setting the tag to NO turns the diagrams off. Note that this
-# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or
+# super classes. Setting the tag to NO turns the diagrams off. Note that this
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is
# recommended to install and use dot, since it yields more powerful graphs.
CLASS_DIAGRAMS = YES
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
# or is not a class.
HIDE_UNDOC_RELATIONS = YES
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
# have no effect if this option is set to NO (the default)
HAVE_DOT = NO
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
# the CLASS_DIAGRAMS tag to NO.
CLASS_GRAPH = YES
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
# class references variables) of the class with other documented classes.
COLLABORATION_GRAPH = YES
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
UML_LOOK = NO
-# If set to YES, the inheritance and collaboration graphs will show the
+# If set to YES, the inheritance and collaboration graphs will show the
# relations between templates and their instances.
TEMPLATE_RELATIONS = NO
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
# other documented files.
INCLUDE_GRAPH = YES
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
# indirectly include this file.
INCLUDED_BY_GRAPH = YES
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
# functions only using the \callgraph command.
CALL_GRAPH = NO
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
# will graphical hierarchy of all classes instead of a textual one.
GRAPHICAL_HIERARCHY = YES
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. Possible values are png, jpg, or gif
# If left blank png will be used.
DOT_IMAGE_FORMAT = png
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found on the path.
-DOT_PATH =
+DOT_PATH =
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
# \dotfile command).
-DOTFILE_DIRS =
+DOTFILE_DIRS =
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_WIDTH = 1024
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than
+# this value, doxygen will try to truncate the graph, so that it fits within
+# the specified constraint. Beware that most browsers cannot cope with very
# large images.
MAX_DOT_GRAPH_HEIGHT = 1024
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes that
-# lay further from the root node will be omitted. Note that setting this option to
-# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
-# note that a graph may be further truncated if the graph's image dimensions are
-# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes that
+# lay further from the root node will be omitted. Note that setting this option to
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that a graph may be further truncated if the graph's image dimensions are
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT).
# If 0 is used for the depth value (the default), the graph is not depth-constrained.
MAX_DOT_GRAPH_DEPTH = 0
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
# arrows in the dot generated graphs.
GENERATE_LEGEND = YES
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
# the various graphs.
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
+# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
-# The SEARCHENGINE tag specifies whether or not a search engine should be
+# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
SHOW_DIRECTORIES=NO
-
diff --git a/libpulse-browse.pc.in b/libpulse-browse.pc.in
index 66438b2a..54705b3f 100644
--- a/libpulse-browse.pc.in
+++ b/libpulse-browse.pc.in
@@ -1,11 +1,12 @@
prefix=@prefix@
-exec_prefix=${prefix}
+exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir=${prefix}/include
+includedir=@includedir@
Name: libpulse-browse
-Description: PulseAudio Network Browsing API
+Description: PulseAudio Network Browsing Interface
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpulse-browse @PTHREAD_LIBS@
-Cflags: -D_REENTRANT -I${includedir}
+Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
+Cflags: -I${includedir} -D_REENTRANT
Requires: libpulse
diff --git a/libpulse-mainloop-glib.pc.in b/libpulse-mainloop-glib.pc.in
index 1a8bfa40..45ae47c7 100644
--- a/libpulse-mainloop-glib.pc.in
+++ b/libpulse-mainloop-glib.pc.in
@@ -1,11 +1,12 @@
prefix=@prefix@
-exec_prefix=${prefix}
+exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir=${prefix}/include
+includedir=@includedir@
Name: libpulse-mainloop-glib
-Description: GLIB 2.0 Main Loop Wrapper for PulseAudio
+Description: PulseAudio GLib 2.0 Main Loop Wrapper
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpulse-mainloop-glib @PTHREAD_LIBS@
-Cflags: -D_REENTRANT -I${includedir}
+Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
+Cflags: -I${includedir} -D_REENTRANT
Requires: libpulse glib-2.0
diff --git a/libpulse-simple.pc.in b/libpulse-simple.pc.in
index 00d1245a..443be289 100644
--- a/libpulse-simple.pc.in
+++ b/libpulse-simple.pc.in
@@ -1,11 +1,12 @@
prefix=@prefix@
-exec_prefix=${prefix}
+exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir=${prefix}/include
+includedir=@includedir@
Name: libpulse-simple
-Description: Simplified Synchronous Client Interface to PulseAudio
+Description: PulseAudio Simplified Synchronous Client Interface
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpulse-simple @PTHREAD_LIBS@
-Cflags: -D_REENTRANT -I${includedir}
+Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
+Cflags: -I${includedir} -D_REENTRANT
Requires: libpulse
diff --git a/libpulse.pc.in b/libpulse.pc.in
index 2193b2b9..161599e1 100644
--- a/libpulse.pc.in
+++ b/libpulse.pc.in
@@ -1,10 +1,11 @@
prefix=@prefix@
-exec_prefix=${prefix}
+exec_prefix=@exec_prefix@
libdir=@libdir@
-includedir=${prefix}/include
+includedir=@includedir@
Name: libpulse
-Description: Client Interface to PulseAudio
+Description: PulseAudio Client Interface
Version: @PACKAGE_VERSION@
Libs: -L${libdir} -lpulse @PTHREAD_LIBS@
-Cflags: -D_REENTRANT -I${includedir}
+Libs.private: -lpulsecommon-@PA_MAJORMINORMICRO@
+Cflags: -I${includedir} -D_REENTRANT
diff --git a/m4/.gitignore b/m4/.gitignore
index ac5d1406..8b81e54b 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1,3 +1,12 @@
+ChangeLog
+gettext.m4
+iconv.m4
+lib-ld.m4
+lib-link.m4
+lib-prefix.m4
+nls.m4
+po.m4
+progtest.m4
argz.m4
intltool.m4
libtool.m4
diff --git a/m4/attributes.m4 b/m4/attributes.m4
new file mode 100644
index 00000000..9c4a0c89
--- /dev/null
+++ b/m4/attributes.m4
@@ -0,0 +1,258 @@
+dnl Macros to check the presence of generic (non-typed) symbols.
+dnl Copyright (c) 2006-2007 Diego Pettenò <flameeyes@gmail.com>
+dnl Copyright (c) 2006-2007 xine project
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2, or (at your option)
+dnl any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+dnl 02110-1301, USA.
+dnl
+dnl As a special exception, the copyright owners of the
+dnl macro gives unlimited permission to copy, distribute and modify the
+dnl configure scripts that are the output of Autoconf when processing the
+dnl Macro. You need not follow the terms of the GNU General Public
+dnl License when using or distributing such scripts, even though portions
+dnl of the text of the Macro appear in them. The GNU General Public
+dnl License (GPL) does govern all other use of the material that
+dnl constitutes the Autoconf Macro.
+dnl
+dnl This special exception to the GPL applies to versions of the
+dnl Autoconf Macro released by this project. When you make and
+dnl distribute a modified version of the Autoconf Macro, you may extend
+dnl this special exception to the GPL to apply to your modified version as
+dnl well.
+
+AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
+ AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_COMPILE_IFELSE([int a;],
+ [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+AC_DEFUN([CC_CHECK_CFLAGS], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_cflags_$1]),
+ CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
+ )
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+AC_DEFUN([CC_CHECK_LDFLAGS], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_ldflags_$1]),
+ [ac_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $1"
+ AC_LINK_IFELSE([int main() { return 1; }],
+ [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_ldflags_$1])="])
+ LDFLAGS="$ac_save_LDFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl Check for a -Werror flag or equivalent. -Werror is the GCC
+dnl and ICC flag that tells the compiler to treat all the warnings
+dnl as fatal. We usually need this option to make sure that some
+dnl constructs (like attributes) are not simply ignored.
+dnl
+dnl Other compilers don't support -Werror per se, but they support
+dnl an equivalent flag:
+dnl - Sun Studio compiler supports -errwarn=%all
+AC_DEFUN([CC_CHECK_WERROR], [
+ AC_CACHE_CHECK(
+ [for $CC way to treat warnings as errors],
+ [cc_cv_werror],
+ [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
+ [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
+ ])
+])
+
+AC_DEFUN([CC_CHECK_ATTRIBUTE], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
+ AS_TR_SH([cc_cv_attribute_$1]),
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_COMPILE_IFELSE([$3],
+ [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
+ [AC_DEFINE(
+ AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
+ [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
+ )
+ $4],
+ [$5])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
+ CC_CHECK_ATTRIBUTE(
+ [constructor],,
+ [void __attribute__((constructor)) ctor() { int a; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
+ CC_CHECK_ATTRIBUTE(
+ [format], [format(printf, n, n)],
+ [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
+ CC_CHECK_ATTRIBUTE(
+ [format_arg], [format_arg(printf)],
+ [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
+ CC_CHECK_ATTRIBUTE(
+ [visibility_$1], [visibility("$1")],
+ [void __attribute__((visibility("$1"))) $1_function() { }],
+ [$2], [$3])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
+ CC_CHECK_ATTRIBUTE(
+ [nonnull], [nonnull()],
+ [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
+ CC_CHECK_ATTRIBUTE(
+ [unused], ,
+ [void some_function(void *foo, __attribute__((unused)) void *bar);],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
+ CC_CHECK_ATTRIBUTE(
+ [sentinel], ,
+ [void some_function(void *foo, ...) __attribute__((sentinel));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
+ CC_CHECK_ATTRIBUTE(
+ [deprecated], ,
+ [void some_function(void *foo, ...) __attribute__((deprecated));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
+ CC_CHECK_ATTRIBUTE(
+ [alias], [weak, alias],
+ [void other_function(void *foo) { }
+ void some_function(void *foo) __attribute__((weak, alias("other_function")));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
+ CC_CHECK_ATTRIBUTE(
+ [malloc], ,
+ [void * __attribute__((malloc)) my_alloc(int n);],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_PACKED], [
+ CC_CHECK_ATTRIBUTE(
+ [packed], ,
+ [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONST], [
+ CC_CHECK_ATTRIBUTE(
+ [const], ,
+ [int __attribute__((const)) twopow(int n) { return 1 << n; } ],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_FLAG_VISIBILITY], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
+ [cc_cv_flag_visibility],
+ [cc_flag_visibility_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
+ cc_cv_flag_visibility='yes',
+ cc_cv_flag_visibility='no')
+ CFLAGS="$cc_flag_visibility_save_CFLAGS"])
+
+ AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
+ [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
+ [Define this if the compiler supports the -fvisibility flag])
+ $1],
+ [$2])
+])
+
+AC_DEFUN([CC_FUNC_EXPECT], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if compiler has __builtin_expect function],
+ [cc_cv_func_expect],
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_COMPILE_IFELSE(
+ [int some_function() {
+ int a = 3;
+ return (int)__builtin_expect(a, 3);
+ }],
+ [cc_cv_func_expect=yes],
+ [cc_cv_func_expect=no])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([test "x$cc_cv_func_expect" = "xyes"],
+ [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
+ [Define this if the compiler supports __builtin_expect() function])
+ $1],
+ [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
+ [cc_cv_attribute_aligned],
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ for cc_attribute_align_try in 64 32 16 8 4 2; do
+ AC_COMPILE_IFELSE([
+ int main() {
+ static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
+ return c;
+ }], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
+ done
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ if test "x$cc_cv_attribute_aligned" != "x"; then
+ AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
+ [Define the highest alignment supported])
+ fi
+])
diff --git a/m4/tls.m4 b/m4/tls.m4
new file mode 100644
index 00000000..3808f06e
--- /dev/null
+++ b/m4/tls.m4
@@ -0,0 +1,17 @@
+AC_DEFUN([CC_CHECK_TLS], [
+ AC_CACHE_CHECK([whether $CC knows __thread for Thread-Local Storage],
+ cc_cv_tls___thread,
+ [AC_COMPILE_IFELSE(
+ AC_LANG_PROGRAM(
+ [[static __thread int a = 6;]],
+ [[a = 5;]]),
+ [cc_cv_tls___thread=yes],
+ [cc_cv_tls___thread=no])
+ ])
+
+ AS_IF([test "x$cc_cv_tls___thread" = "xyes"],
+ [AC_DEFINE([SUPPORT_TLS___THREAD], 1,
+ [Define this if the compiler supports __thread for Thread-Local Storage])
+ $1],
+ [$2])
+])
diff --git a/man/Makefile.am b/man/Makefile.am
index b0536d84..9b229f52 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -17,9 +17,10 @@
pulseconfdir=$(sysconfdir)/pulse
-if BUILD_MANPAGES
+CLEANFILES = \
+ $(noinst_DATA)
-man_MANS = \
+dist_man_MANS = \
pulseaudio.1 \
esdcompat.1 \
pax11publish.1 \
@@ -49,115 +50,18 @@ noinst_DATA = \
pulse-client.conf.5.xml \
default.pa.5.xml
-CLEANFILES = \
- $(noinst_DATA)
-
-pulseaudio.1.xml: pulseaudio.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-esdcompat.1.xml: esdcompat.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pax11publish.1.xml: pax11publish.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-paplay.1.xml: paplay.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pacat.1.xml: pacat.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pacmd.1.xml: pacmd.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pactl.1.xml: pactl.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pasuspender.1.xml: pasuspender.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-padsp.1.xml: padsp.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pabrowse.1.xml: pabrowse.1.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-
-pulse-daemon.conf.5.xml: pulse-daemon.conf.5.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
+if BUILD_MANPAGES
-pulse-client.conf.5.xml: pulse-client.conf.5.xml.in Makefile
- sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
- -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
- -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
+CLEANFILES += \
+ $(dist_man_MANS)
-default.pa.5.xml: default.pa.5.xml.in Makefile
+%.xml: %.xml.in Makefile
sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
-e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
-e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
-CLEANFILES += \
- $(man_MANS)
-
-pulseaudio.1: pulseaudio.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-esdcompat.1: esdcompat.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pax11publish.1: pax11publish.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-paplay.1: paplay.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pacat.1: pacat.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pacmd.1: pacmd.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pactl.1: pactl.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pasuspender.1: pasuspender.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-padsp.1: padsp.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pabrowse.1: pabrowse.1.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pulse-daemon.conf.5: pulse-daemon.conf.5.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-pulse-client.conf.5: pulse-client.conf.5.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
-
-default.pa.5: default.pa.5.xml Makefile
- perl xmltoman $< > $@ || rm -f $@
+%: %.xml Makefile
+ perl $(srcdir)/xmltoman $< > $@ || rm -f $@
xmllint: $(noinst_DATA)
for f in $(noinst_DATA) ; do \
@@ -167,7 +71,6 @@ xmllint: $(noinst_DATA)
endif
EXTRA_DIST = \
- $(man_MANS) \
pulseaudio.1.xml.in \
esdcompat.1.xml.in \
pax11publish.1.xml.in \
diff --git a/man/pacat.1.xml.in b/man/pacat.1.xml.in
index 7b0d72b9..68a3a12a 100644
--- a/man/pacat.1.xml.in
+++ b/man/pacat.1.xml.in
@@ -108,9 +108,11 @@ USA.
<optdesc><p>Capture or play back audio with the specified sample
format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
- <opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
+ <opt>s16be</opt>, <opt>s32le</opt>,
+ <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
- the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
+ the CPU the
+ formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
<opt>float32ne</opt>, <opt>float32re</opt> (for native,
resp. reverse endian) are available as aliases. Defaults to
s16ne.</p></optdesc>
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 50e24559..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>,
@@ -106,6 +111,16 @@ USA.
</option>
<option>
+ <p><opt>disable-lfe-remixing=</opt> When upmixing or downmixing
+ ignore LFE channels. When this option is on the output LFE
+ channel will only get a signal when an input LFE channel is
+ 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. Defaults to "on".</p>
+ </option>
+
+ <option>
<p><opt>use-pid-file=</opt> Create a PID file in
<file>/tmp/pulse-$USER/pid</file>. Of this is enabled you may
use commands like <opt>--kill</opt> or <opt>--check</opt>. If
@@ -141,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">
@@ -230,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>
@@ -272,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>
@@ -290,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>
@@ -307,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>
@@ -319,9 +366,11 @@ USA.
<option>
<p><opt>default-sample-format=</opt> The default sampling
format. Specify one of <opt>u8</opt>, <opt>s16le</opt>,
- <opt>s16be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
+ <opt>s16be</opt>, <opt>s32le</opt>,
+ <opt>s32be</opt>, <opt>float32le</opt>, <opt>float32be</opt>,
<opt>ulaw</opt>, <opt>alaw</opt>. Depending on the endianess of
- the CPU the formats <opt>s16ne</opt>, <opt>s16re</opt>,
+ the CPU the
+ formats <opt>s16ne</opt>, <opt>s16re</opt>, <opt>s32ne</opt>, <opt>s32re</opt>,
<opt>float32ne</opt>, <opt>float32re</opt> (for native,
resp. reverse endian) are available as aliases.</p>
</option>
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/LINGUAS b/po/LINGUAS
index 7673daa9..3aa8efdf 100644
--- a/po/LINGUAS
+++ b/po/LINGUAS
@@ -1 +1,6 @@
de
+el
+fr
+pl
+pt_BR
+sv
diff --git a/po/POTFILES.in b/po/POTFILES.in
index fa28b6a7..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
@@ -190,3 +190,4 @@ src/utils/padsp.c
src/utils/pax11publish.c
src/utils/pacmd.c
src/utils/paplay.c
+src/pulsecore/lock-autospawn.c
diff --git a/po/de.po b/po/de.po
index 2a7c5deb..b587e21c 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1,67 +1,68 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+# German translation of pulseaudio
+# Copyright (C) 2008 pulseaudio
+# This file is distributed under the same license as the pulseaudio package.
+# Fabian Affolter <fab@fedoraproject.org>, 2008.
#
msgid ""
msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
+"Project-Id-Version: pulseaudio\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2008-08-06 20:24+0200\n"
-"PO-Revision-Date: 2008-08-06 20:34+0100\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: LANGUAGE <LL@li.org>\n"
+"Language-Team: German <fedora-trans-de@redhat.com>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Poedit-Language: German\n"
-#: ../src/daemon/ltdl-bind-now.c:171
-#: ../src/daemon/ltdl-bind-now.c:191
+#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
msgid "Failed to add bind-now-loader."
-msgstr ""
+msgstr "Hinzufügen von Bind-Now-Loader fehlgeschlagen."
-#: ../src/daemon/ltdl-bind-now.c:178
+#: ../src/daemon/ltdl-bind-now.c:184
msgid "Failed to find original dlopen loader."
-msgstr ""
+msgstr "Finden von originalem dlopen-Loader fehlgeschlagen."
#: ../src/daemon/polkit.c:55
#, c-format
msgid "Cannot connect to system bus: %s"
-msgstr ""
+msgstr "Kann nicht mit dem System-Bus verbinden: %s"
#: ../src/daemon/polkit.c:65
#, c-format
msgid "Cannot get caller from PID: %s"
-msgstr ""
+msgstr "Kann Caller von PID nicht beziehen: %s"
#: ../src/daemon/polkit.c:77
msgid "Cannot set UID on caller object."
-msgstr ""
+msgstr "Kann Caller-Ojekt für UID nicht setzen."
#: ../src/daemon/polkit.c:82
msgid "Failed to get CK session."
-msgstr ""
+msgstr "Kann CK-Session nicht beziehen."
#: ../src/daemon/polkit.c:90
msgid "Cannot set UID on session object."
-msgstr ""
+msgstr "Kann UID auf Session-Objekt nicht setzen."
#: ../src/daemon/polkit.c:95
msgid "Cannot allocate PolKitAction."
-msgstr ""
+msgstr "Konnte PolKitAction nicht allozieren."
#: ../src/daemon/polkit.c:100
msgid "Cannot set action_id"
-msgstr ""
+msgstr "Kann action_id nicht setzen"
#: ../src/daemon/polkit.c:105
msgid "Cannot allocate PolKitContext."
-msgstr ""
+msgstr "Konnte PolKitContext nicht allozieren"
#: ../src/daemon/polkit.c:110
#, c-format
msgid "Cannot initialize PolKitContext: %s"
-msgstr ""
+msgstr "Konnte PolKitContect nicht initialisieren: %s"
#: ../src/daemon/polkit.c:119
#, c-format
@@ -71,84 +72,83 @@ msgstr ""
#: ../src/daemon/polkit.c:139
#, c-format
msgid "Cannot obtain auth: %s"
-msgstr ""
+msgstr "Erhalten der Authorisierung fehlgeschlagen: %s"
#: ../src/daemon/polkit.c:148
#, c-format
msgid "PolicyKit responded with '%s'"
-msgstr ""
+msgstr "PolicyKit antwortet mit '%s'"
-#: ../src/daemon/main.c:135
+#: ../src/daemon/main.c:134
#, c-format
msgid "Got signal %s."
msgstr "Signal %s empfangen."
-#: ../src/daemon/main.c:162
+#: ../src/daemon/main.c:161
msgid "Exiting."
msgstr "Beende."
-#: ../src/daemon/main.c:180
+#: ../src/daemon/main.c:179
#, c-format
msgid "Failed to find user '%s'."
-msgstr ""
+msgstr "Kann Benutzer '%s' nicht finden."
-#: ../src/daemon/main.c:185
+#: ../src/daemon/main.c:184
#, c-format
msgid "Failed to find group '%s'."
-msgstr ""
+msgstr "Kann Gruppe '%s' nicht finden."
-#: ../src/daemon/main.c:189
+#: ../src/daemon/main.c:188
#, c-format
msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
-msgstr ""
+msgstr "Fand Benutzer '%s' (UID %lu) und Gruppe '%s' (GID %lu)."
-#: ../src/daemon/main.c:194
+#: ../src/daemon/main.c:193
#, c-format
msgid "GID of user '%s' and of group '%s' don't match."
-msgstr ""
+msgstr "GID von Benutzer '%s' und von Gruppe '%s' stimme nicht überein."
-#: ../src/daemon/main.c:199
+#: ../src/daemon/main.c:198
#, c-format
msgid "Home directory of user '%s' is not '%s', ignoring."
-msgstr ""
+msgstr "Benutzerverzeichnis von Benutzer '%s' ist nicht '%s', ignoriere."
-#: ../src/daemon/main.c:202
-#: ../src/daemon/main.c:207
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
#, c-format
msgid "Failed to create '%s': %s"
-msgstr ""
+msgstr "Erzeugen von '%s' fehlgeschlagen: %s"
-#: ../src/daemon/main.c:214
+#: ../src/daemon/main.c:213
#, c-format
msgid "Failed to change group list: %s"
-msgstr ""
+msgstr "Wechseln der Gruppen-Liste fehlgeschlagen: %s"
-#: ../src/daemon/main.c:230
+#: ../src/daemon/main.c:229
#, c-format
msgid "Failed to change GID: %s"
-msgstr ""
+msgstr "Wechseln der GID fehlgeschlagen: %s"
-#: ../src/daemon/main.c:246
+#: ../src/daemon/main.c:245
#, c-format
msgid "Failed to change UID: %s"
-msgstr ""
+msgstr "Wechseln der UID fehlgeschlagen: %s"
-#: ../src/daemon/main.c:260
+#: ../src/daemon/main.c:259
msgid "Successfully dropped root privileges."
-msgstr ""
+msgstr "Root-Berechtigungen erfolgreich zurückgesetzt."
-#: ../src/daemon/main.c:268
+#: ../src/daemon/main.c:267
msgid "System wide mode unsupported on this platform."
-msgstr ""
+msgstr "System-Modus auf dieser Plattform nicht unterstützt."
-#: ../src/daemon/main.c:286
+#: ../src/daemon/main.c:285
#, c-format
msgid "setrlimit(%s, (%u, %u)) failed: %s"
-msgstr ""
+msgstr "setrlimit(%s, (%u, %u)) fehlgeschlagen: %s"
#: ../src/daemon/main.c:425
msgid "Failed to parse command line."
-msgstr ""
+msgstr "Parsen der Kommandzeile fehlgeschlagen."
#: ../src/daemon/main.c:441
#, c-format
@@ -178,55 +178,61 @@ 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: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
msgid "Successfully increased RLIMIT_RTPRIO"
-msgstr ""
+msgstr "RLIMIT_RTPRIO erfolgreich erhöht"
#: ../src/daemon/main.c:525
#, c-format
msgid "RLIMIT_RTPRIO failed: %s"
-msgstr ""
+msgstr "RLIMIT_RTPRIO fehlgeschlagen: %s"
#: ../src/daemon/main.c:532
msgid "Giving up CAP_NICE"
-msgstr ""
+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
msgid "Daemon not running"
-msgstr ""
+msgstr "Daemon läuft nicht"
#: ../src/daemon/main.c:599
#, c-format
msgid "Daemon running as PID %u"
-msgstr ""
+msgstr "Daemon läuft als PID %u"
#: ../src/daemon/main.c:609
-msgid "Failed to kill daemon."
-msgstr ""
+#, c-format
+msgid "Failed to kill daemon: %s"
+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
msgid "Root priviliges required."
-msgstr ""
+msgstr "Root-Berechtigungen benötigt."
#: ../src/daemon/main.c:634
msgid "--start not supported for system instances."
-msgstr ""
+msgstr "--start nicht unterstützt für System-Instanzen."
#: ../src/daemon/main.c:639
msgid "Running in system mode, but --disallow-exit not set!"
@@ -244,101 +250,148 @@ msgstr ""
msgid "Running in system mode, forcibly disabling exit idle time!"
msgstr ""
-#: ../src/daemon/main.c:668
+#: ../src/daemon/main.c:677
msgid "Failed to acquire stdio."
-msgstr ""
+msgstr "Reservieren von STDIO fehlgeschlagen."
-#: ../src/daemon/main.c:674
+#: ../src/daemon/main.c:683
#, c-format
msgid "pipe failed: %s"
-msgstr ""
+msgstr "pipe fehlgeschlagen: %s"
-#: ../src/daemon/main.c:679
+#: ../src/daemon/main.c:688
#, c-format
msgid "fork() failed: %s"
-msgstr ""
+msgstr "fork() fehlgeschlagen: %s"
-#: ../src/daemon/main.c:693
+#: ../src/daemon/main.c:702
#, c-format
msgid "read() failed: %s"
-msgstr ""
+msgstr "read() fehlgeschlagen: %s"
-#: ../src/daemon/main.c:699
+#: ../src/daemon/main.c:708
msgid "Daemon startup failed."
msgstr "Start des Dämons fehlgeschlagen."
-#: ../src/daemon/main.c:701
+#: ../src/daemon/main.c:710
msgid "Daemon startup successful."
msgstr "Start des Dämons erfolgreich."
-#: ../src/daemon/main.c:768
+#: ../src/daemon/main.c:780
#, c-format
msgid "This is PulseAudio %s"
msgstr "Dies ist PulseAudio %s"
-#: ../src/daemon/main.c:769
+#: ../src/daemon/main.c:781
+#, c-format
+msgid "Compilation host: %s"
+msgstr "Kompilations-Host: %s"
+
+#: ../src/daemon/main.c:782
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr "Kompilier-CFLAGS: %s"
+
+#: ../src/daemon/main.c:785
+#, c-format
+msgid "Running on host: %s"
+msgstr "Laufe auf Host: %s"
+
+#: ../src/daemon/main.c:788
#, c-format
msgid "Page size is %lu bytes"
msgstr "Seitengröße ist %lu Bytes."
-#: ../src/daemon/main.c:772
+#: ../src/daemon/main.c:791
+msgid "Compiled with Valgrind support: yes"
+msgstr "Kompiliere mit Valgrind-Unterstützung: ja"
+
+#: ../src/daemon/main.c:793
+msgid "Compiled with Valgrind support: no"
+msgstr "Kompiliere mit Valgrind-Unterstützung: nein"
+
+#: ../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:801
+msgid "Optimized build: no"
+msgstr "Optimiertes Build: nein"
+
+#: ../src/daemon/main.c:805
+msgid "Failed to get machine ID"
+msgstr "Beziehen der Maschinen-ID fehlgeschlagen"
+
+#: ../src/daemon/main.c:808
+#, c-format
+msgid "Machine ID is %s."
+msgstr "System- ID ist %s."
+
+#: ../src/daemon/main.c:813
#, c-format
msgid "Using runtime directory %s."
-msgstr ""
+msgstr "Nutze Laufzeit-Verzeichnis %s."
-#: ../src/daemon/main.c:775
+#: ../src/daemon/main.c:818
#, c-format
msgid "Using state directory %s."
-msgstr ""
+msgstr "Nutze Zustands-Verzeichnis %s."
-#: ../src/daemon/main.c:778
+#: ../src/daemon/main.c:821
#, c-format
msgid "Running in system mode: %s"
-msgstr ""
+msgstr "Laufe im System-Modus: %s"
-#: ../src/daemon/main.c:793
+#: ../src/daemon/main.c:836
msgid "pa_pid_file_create() failed."
-msgstr ""
+msgstr "pa_pid_file_create() fehlgeschlagen."
-#: ../src/daemon/main.c:805
+#: ../src/daemon/main.c:848
msgid "Fresh high-resolution timers available! Bon appetit!"
msgstr ""
-#: ../src/daemon/main.c:807
-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:817
+#: ../src/daemon/main.c:860
msgid "pa_core_new() failed."
-msgstr ""
+msgstr "pa_core_new() fehlgeschlagen."
-#: ../src/daemon/main.c:877
+#: ../src/daemon/main.c:921
msgid "Failed to initialize daemon."
-msgstr ""
+msgstr "Konnte Dämon nicht initialisieren"
-#: ../src/daemon/main.c:882
+#: ../src/daemon/main.c:926
msgid "Daemon startup without any loaded modules, refusing to work."
msgstr ""
-#: ../src/daemon/main.c:887
+#: ../src/daemon/main.c:931
#, c-format
msgid "Default sink name (%s) does not exist in name register."
msgstr ""
-#: ../src/daemon/main.c:900
+#: ../src/daemon/main.c:944
msgid "Daemon startup complete."
msgstr "Start des Dämons abgeschlossen."
-#: ../src/daemon/main.c:906
+#: ../src/daemon/main.c:950
msgid "Daemon shutdown initiated."
-msgstr ""
+msgstr "Herunterfahren des Daemon gestartet."
-#: ../src/daemon/main.c:923
+#: ../src/daemon/main.c:971
msgid "Daemon terminated."
msgstr "Dämon beendet."
#: ../src/daemon/cmdline.c:117
-#, c-format
+#, fuzzy, c-format
msgid ""
"%s [options]\n"
"\n"
@@ -348,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"
@@ -358,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"
@@ -386,14 +448,80 @@ 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"
msgstr ""
+"%s [options]\n"
+"\n"
+"COMMANDS:\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+" --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"
+" -k --kill Kill a running daemon\n"
+" --check Check for a running daemon\n"
+"\n"
+"OPTIONS:\n"
+" --system[=BOOL] Run as system-wide instance\n"
+" -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"
+" with elevated RLIMIT_NICE)\n"
+" --realtime[=BOOL] Try to enable realtime scheduling\n"
+" (only available as root, when SUID "
+"or\n"
+" with elevated RLIMIT_RTPRIO)\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"
+" time passed\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"
+" 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"
+" objects (plugins)\n"
+" --resample-method=METHOD Use the specified resampling method\n"
+" (See --dump-resample-methods for\n"
+" possible values)\n"
+" --use-pid-file[=BOOL] Create a PID file\n"
+" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
+" platforms that support it.\n"
+" --disable-shm[=BOOL] Disable shared memory support.\n"
+"\n"
+"STARTUP SCRIPT:\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"
+" after startup\n"
+"\n"
+" -n Don't load default script file\n"
#: ../src/daemon/cmdline.c:245
msgid "--daemonize expects boolean argument"
@@ -404,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
@@ -430,15 +560,16 @@ 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'."
#: ../src/daemon/cmdline.c:338
#, c-format
msgid "Invalid resample method '%s'."
-msgstr ""
+msgstr "Ungültige Resample-Methode '%s'."
#: ../src/daemon/cmdline.c:345
msgid "--system expects boolean argument"
-msgstr ""
+msgstr "--System erwartet Boolean-Argument"
#: ../src/daemon/cmdline.c:352
msgid "--no-cpu-limit expects boolean argument"
@@ -451,113 +582,113 @@ msgstr ""
#: ../src/daemon/dumpmodules.c:60
#, c-format
msgid "Name: %s\n"
-msgstr ""
+msgstr "Name: %s\n"
#: ../src/daemon/dumpmodules.c:63
#, c-format
msgid "No module information available\n"
-msgstr ""
+msgstr "Keine Modul-Informationen verfügbar\n"
#: ../src/daemon/dumpmodules.c:66
#, c-format
msgid "Version: %s\n"
-msgstr ""
+msgstr "Version: %s\n"
#: ../src/daemon/dumpmodules.c:68
#, c-format
msgid "Description: %s\n"
-msgstr ""
+msgstr "Beschreibung: %s\n"
#: ../src/daemon/dumpmodules.c:70
#, c-format
msgid "Author: %s\n"
-msgstr ""
+msgstr "Author: %s\n"
#: ../src/daemon/dumpmodules.c:72
#, c-format
msgid "Usage: %s\n"
-msgstr ""
+msgstr "Verwendung: %s\n"
#: ../src/daemon/dumpmodules.c:73
#, c-format
msgid "Load Once: %s\n"
-msgstr ""
+msgstr "Lade einmalig: %s\n"
#: ../src/daemon/dumpmodules.c:77
#, c-format
msgid "Path: %s\n"
-msgstr ""
+msgstr "Pfad: %s\n"
-#: ../src/daemon/daemon-conf.c:203
+#: ../src/daemon/daemon-conf.c:205
#, c-format
msgid "[%s:%u] Invalid log target '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültiges Log-Ziel '%s'."
-#: ../src/daemon/daemon-conf.c:219
+#: ../src/daemon/daemon-conf.c:221
#, c-format
msgid "[%s:%u] Invalid log level '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Log-Stufe '%s'."
-#: ../src/daemon/daemon-conf.c:235
+#: ../src/daemon/daemon-conf.c:237
#, c-format
msgid "[%s:%u] Invalid resample method '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Resample-Methode '%s'."
-#: ../src/daemon/daemon-conf.c:258
+#: ../src/daemon/daemon-conf.c:260
#, c-format
msgid "[%s:%u] Invalid rlimit '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültiges rlimit '%s'."
-#: ../src/daemon/daemon-conf.c:265
+#: ../src/daemon/daemon-conf.c:267
#, c-format
msgid "[%s:%u] rlimit not supported on this platform."
-msgstr ""
+msgstr "[%s:%u] rlimit nicht unterstützt auf dieser Plattform."
-#: ../src/daemon/daemon-conf.c:281
+#: ../src/daemon/daemon-conf.c:283
#, c-format
msgid "[%s:%u] Invalid sample format '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültiges Sample-Format '%s'."
-#: ../src/daemon/daemon-conf.c:299
+#: ../src/daemon/daemon-conf.c:301
#, c-format
msgid "[%s:%u] Invalid sample rate '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Sample-Rate '%s'."
-#: ../src/daemon/daemon-conf.c:317
+#: ../src/daemon/daemon-conf.c:319
#, c-format
msgid "[%s:%u] Invalid sample channels '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Sample-Kanäle '%s'."
-#: ../src/daemon/daemon-conf.c:335
+#: ../src/daemon/daemon-conf.c:337
#, c-format
msgid "[%s:%u] Invalid number of fragments '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Anzahl von Fragmenten '%s'."
-#: ../src/daemon/daemon-conf.c:353
+#: ../src/daemon/daemon-conf.c:355
#, c-format
msgid "[%s:%u] Invalid fragment size '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Fragment-Größe '%s'."
-#: ../src/daemon/daemon-conf.c:371
+#: ../src/daemon/daemon-conf.c:373
#, c-format
msgid "[%s:%u] Invalid nice level '%s'."
-msgstr ""
+msgstr "[%s:%u] Ungültige Nice-Stufe '%s'."
-#: ../src/daemon/daemon-conf.c:564
+#: ../src/daemon/daemon-conf.c:570
#, c-format
msgid "Failed to open configuration file: %s"
-msgstr ""
+msgstr "Öffnen der Konfigurationsdatei fehlgeschlagen : %s"
-#: ../src/daemon/daemon-conf.c:638
+#: ../src/daemon/daemon-conf.c:644
#, c-format
msgid "### Read from configuration file: %s ###\n"
-msgstr ""
+msgstr "### Lesen von Konfigurationsdatei: %s ###\n"
-#: ../src/daemon/caps.c:62
+#: ../src/daemon/caps.c:63
msgid "Dropping root priviliges."
-msgstr ""
+msgstr "Gebe Root-Privilegien auf."
-#: ../src/daemon/caps.c:102
+#: ../src/daemon/caps.c:103
msgid "Limited capabilities successfully to CAP_SYS_NICE."
msgstr ""
@@ -611,131 +742,131 @@ msgstr "Seite Rechts"
#: ../src/pulse/channelmap.c:120
msgid "Auxiliary 0"
-msgstr ""
+msgstr "Zusatz 0"
#: ../src/pulse/channelmap.c:121
msgid "Auxiliary 1"
-msgstr ""
+msgstr "Zusatz 1"
#: ../src/pulse/channelmap.c:122
msgid "Auxiliary 2"
-msgstr ""
+msgstr "Zusatz 2"
#: ../src/pulse/channelmap.c:123
msgid "Auxiliary 3"
-msgstr ""
+msgstr "Zusatz 3"
#: ../src/pulse/channelmap.c:124
msgid "Auxiliary 4"
-msgstr ""
+msgstr "Zusatz 4"
#: ../src/pulse/channelmap.c:125
msgid "Auxiliary 5"
-msgstr ""
+msgstr "Zusatz 5"
#: ../src/pulse/channelmap.c:126
msgid "Auxiliary 6"
-msgstr ""
+msgstr "Zusatz 6"
#: ../src/pulse/channelmap.c:127
msgid "Auxiliary 7"
-msgstr ""
+msgstr "Zusatz 7"
#: ../src/pulse/channelmap.c:128
msgid "Auxiliary 8"
-msgstr ""
+msgstr "Zusatz 8"
#: ../src/pulse/channelmap.c:129
msgid "Auxiliary 9"
-msgstr ""
+msgstr "Zusatz 9"
#: ../src/pulse/channelmap.c:130
msgid "Auxiliary 10"
-msgstr ""
+msgstr "Zusatz 10"
#: ../src/pulse/channelmap.c:131
msgid "Auxiliary 11"
-msgstr ""
+msgstr "Zusatz 11"
#: ../src/pulse/channelmap.c:132
msgid "Auxiliary 12"
-msgstr ""
+msgstr "Zusatz 12"
#: ../src/pulse/channelmap.c:133
msgid "Auxiliary 13"
-msgstr ""
+msgstr "Zusatz 13"
#: ../src/pulse/channelmap.c:134
msgid "Auxiliary 14"
-msgstr ""
+msgstr "Zusatz 14"
#: ../src/pulse/channelmap.c:135
msgid "Auxiliary 15"
-msgstr ""
+msgstr "Zusatz 15"
#: ../src/pulse/channelmap.c:136
msgid "Auxiliary 16"
-msgstr ""
+msgstr "Zusatz 16"
#: ../src/pulse/channelmap.c:137
msgid "Auxiliary 17"
-msgstr ""
+msgstr "Zusatz 17"
#: ../src/pulse/channelmap.c:138
msgid "Auxiliary 18"
-msgstr ""
+msgstr "Zusatz 18"
#: ../src/pulse/channelmap.c:139
msgid "Auxiliary 19"
-msgstr ""
+msgstr "Zusatz 19"
#: ../src/pulse/channelmap.c:140
msgid "Auxiliary 20"
-msgstr ""
+msgstr "Zusatz 20"
#: ../src/pulse/channelmap.c:141
msgid "Auxiliary 21"
-msgstr ""
+msgstr "Zusatz 21"
#: ../src/pulse/channelmap.c:142
msgid "Auxiliary 22"
-msgstr ""
+msgstr "Zusatz 22"
#: ../src/pulse/channelmap.c:143
msgid "Auxiliary 23"
-msgstr ""
+msgstr "Zusatz 23"
#: ../src/pulse/channelmap.c:144
msgid "Auxiliary 24"
-msgstr ""
+msgstr "Zusatz 24"
#: ../src/pulse/channelmap.c:145
msgid "Auxiliary 25"
-msgstr ""
+msgstr "Zusatz 25"
#: ../src/pulse/channelmap.c:146
msgid "Auxiliary 26"
-msgstr ""
+msgstr "Zusatz 26"
#: ../src/pulse/channelmap.c:147
msgid "Auxiliary 27"
-msgstr ""
+msgstr "Zusatz 26"
#: ../src/pulse/channelmap.c:148
msgid "Auxiliary 28"
-msgstr ""
+msgstr "Zusatz 28"
#: ../src/pulse/channelmap.c:149
msgid "Auxiliary 29"
-msgstr ""
+msgstr "Zusatz 29"
#: ../src/pulse/channelmap.c:150
msgid "Auxiliary 30"
-msgstr ""
+msgstr "Zusatz 30"
#: ../src/pulse/channelmap.c:151
msgid "Auxiliary 31"
-msgstr ""
+msgstr "Zusatz 31"
#: ../src/pulse/channelmap.c:153
msgid "Top Center"
@@ -743,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"
@@ -765,9 +896,14 @@ 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 ""
+msgstr "OK"
#: ../src/pulse/error.c:44
msgid "Access denied"
@@ -787,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"
@@ -815,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"
@@ -853,48 +989,34 @@ 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 ""
+msgstr "XOpenDisplay() fehlgeschlagen"
#: ../src/pulse/client-conf-x11.c:78
msgid "Failed to parse cookie data"
-msgstr ""
+msgstr "Parsen der Cookie-Daten fehlgeschlagen"
-#: ../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:110
-msgid "Cannot unlock autospawn because runtime path is no more."
-msgstr ""
+msgstr "Konfigurationsdatei »%s« konnte nicht geöffnet werden: %s"
-#: ../src/pulse/context.c:536
+#: ../src/pulse/context.c:516
msgid "No cookie loaded. Attempting to connect without."
msgstr ""
-#: ../src/pulse/context.c:590
-#, c-format
-msgid "socketpair(): %s"
-msgstr ""
-
-#: ../src/pulse/context.c:604
+#: ../src/pulse/context.c:642
#, c-format
msgid "fork(): %s"
-msgstr ""
+msgstr "fork(): %s"
-#: ../src/pulse/context.c:667
+#: ../src/pulse/context.c:695
#, c-format
msgid "waitpid(): %s"
-msgstr ""
+msgstr "waitpid(): %s"
-#: ../src/pulse/context.c:1265
+#: ../src/pulse/context.c:1256
#, c-format
msgid "Received message for unknown extension '%s'"
msgstr ""
@@ -902,12 +1024,12 @@ msgstr ""
#: ../src/utils/pacat.c:93
#, c-format
msgid "pa_stream_write() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_write() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:132
#, c-format
msgid "pa_stream_peek() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_peek() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:141
#, c-format
@@ -917,17 +1039,17 @@ msgstr ""
#: ../src/utils/pacat.c:143
#, c-format
msgid "pa_stream_drop() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_drop() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:169
#, c-format
msgid "Stream successfully created.\n"
-msgstr ""
+msgstr "Stream wurde erfolgreich erstellt.\n"
#: ../src/utils/pacat.c:172
#, c-format
msgid "pa_stream_get_buffer_attr() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_get_buffer_attr() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:176
#, c-format
@@ -947,37 +1069,37 @@ msgstr ""
#: ../src/utils/pacat.c:187
#, c-format
msgid "Connected to device %s (%u, %ssuspended).\n"
-msgstr ""
+msgstr "Connected to device %s (%u, %ssuspended).\n"
#: ../src/utils/pacat.c:197
#, c-format
msgid "Stream error: %s\n"
-msgstr ""
+msgstr "Stream-Fehler: %s\n"
#: ../src/utils/pacat.c:207
#, c-format
msgid "Stream device suspended.%s \n"
-msgstr ""
+msgstr "Strom-Gerät eingeschlafen.%s\n"
#: ../src/utils/pacat.c:209
#, c-format
msgid "Stream device resumed.%s \n"
-msgstr ""
+msgstr "Stream-Gerät aufgeweckt.%s\n"
#: ../src/utils/pacat.c:217
#, c-format
msgid "Stream underrun.%s \n"
-msgstr ""
+msgstr "Stream underrun.%s \n"
#: ../src/utils/pacat.c:224
-#, c-format
+#, fuzzy, c-format
msgid "Stream overrun.%s \n"
-msgstr ""
+msgstr "Stream overrun.%s \n"
#: ../src/utils/pacat.c:231
#, c-format
msgid "Stream started.%s \n"
-msgstr ""
+msgstr "Stream gestartet: %s\n"
#: ../src/utils/pacat.c:238
#, c-format
@@ -986,93 +1108,88 @@ msgstr ""
#: ../src/utils/pacat.c:238
msgid "not "
-msgstr ""
+msgstr "nicht"
#: ../src/utils/pacat.c:259
#, c-format
msgid "Connection established.%s \n"
-msgstr ""
+msgstr "Verbindung hergestellt.%s \n"
#: ../src/utils/pacat.c:262
#, c-format
msgid "pa_stream_new() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_new() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:287
#, c-format
msgid "pa_stream_connect_playback() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_connect_playback() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:293
#, c-format
msgid "pa_stream_connect_record() failed: %s\n"
-msgstr ""
+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 ""
+msgstr "Verbindungsfehler: %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 ""
+msgstr "Entleeren des Streams fehlgeschlagen: %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 ""
+msgstr "Wiedergabe-Stream entleert.\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 ""
+msgstr "Draining connection to server.\n"
#: ../src/utils/pacat.c:369
#, c-format
msgid "Got EOF.\n"
-msgstr ""
+msgstr "EOF empfangen.\n"
#: ../src/utils/pacat.c:375
#, c-format
msgid "pa_stream_drain(): %s\n"
-msgstr ""
+msgstr "pa_stream_drain(): %s\n"
#: ../src/utils/pacat.c:385
#, c-format
msgid "read() failed: %s\n"
-msgstr ""
+msgstr "read() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:417
#, c-format
msgid "write() failed: %s\n"
-msgstr ""
+msgstr "write() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:438
#, c-format
msgid "Got signal, exiting.\n"
-msgstr ""
+msgstr "Signal empfangen, beende.\n"
#: ../src/utils/pacat.c:452
#, c-format
msgid "Failed to get latency: %s\n"
-msgstr ""
+msgstr "Erhalten der Latenz fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:457
#, c-format
msgid "Time: %0.3f sec; Latency: %0.0f usec. \r"
-msgstr ""
+msgstr "Zeit: %0.3f sec; Latenz: %0.0f usec. \r"
#: ../src/utils/pacat.c:477
#, c-format
msgid "pa_stream_update_timing_info() failed: %s\n"
-msgstr ""
+msgstr "pa_stream_update_timing_info() fehlgeschlagen: %s\n"
#: ../src/utils/pacat.c:490
#, c-format
@@ -1087,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 (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
@@ -1117,26 +1251,29 @@ msgid ""
"Compiled with libpulse %s\n"
"Linked with libpulse %s\n"
msgstr ""
+"pacat %s\n"
+"Kompiliert mit libpulse %s\n"
+"Gelinkt mit libpulse %s\n"
#: ../src/utils/pacat.c:647
#, c-format
msgid "Invalid channel map '%s'\n"
-msgstr ""
+msgstr "Ungültige Kanal-Zuweisung '%s'\n"
#: ../src/utils/pacat.c:676
#, c-format
msgid "Invalid latency specification '%s'\n"
-msgstr ""
+msgstr "Ungültige Latenz-Angaben '%s'\n"
#: ../src/utils/pacat.c:683
#, c-format
msgid "Invalid process time specification '%s'\n"
-msgstr ""
+msgstr "Ungültige Prozesszeit-Angaben '%s'\n"
#: ../src/utils/pacat.c:694
#, c-format
msgid "Invalid sample specification\n"
-msgstr ""
+msgstr "Ungültige Sample-Spezifikationen\n"
#: ../src/utils/pacat.c:699
#, c-format
@@ -1150,108 +1287,114 @@ msgstr ""
#: ../src/utils/pacat.c:706
msgid "recording"
-msgstr ""
+msgstr "aufnehmen"
#: ../src/utils/pacat.c:706
msgid "playback"
-msgstr ""
+msgstr "abspielen"
#: ../src/utils/pacat.c:714
#, c-format
msgid "open(): %s\n"
-msgstr ""
+msgstr "open(): %s\n"
#: ../src/utils/pacat.c:719
#, c-format
msgid "dup2(): %s\n"
-msgstr ""
+msgstr "dup2(): %s\n"
#: ../src/utils/pacat.c:729
#, c-format
msgid "Too many arguments.\n"
-msgstr ""
+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 ""
+msgstr "pa_mainloop_new() fehlgeschlagen.\n"
#: ../src/utils/pacat.c:763
#, c-format
msgid "io_new() failed.\n"
-msgstr ""
+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 ""
+msgstr "pa_context_new() fehlgeschlagen.\n"
+
+#: ../src/utils/pacat.c:777
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_new() fehlgeschlagen: %s"
-#: ../src/utils/pacat.c:785
+#: ../src/utils/pacat.c:788
#, c-format
msgid "time_new() failed.\n"
-msgstr ""
+msgstr "time_new() fehlgeschlagen.\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 ""
+msgstr "pa_mainloop_run() fehlgeschlagen.\n"
#: ../src/utils/pasuspender.c:81
#, c-format
msgid "fork(): %s\n"
-msgstr ""
+msgstr "fork(): %s\n"
#: ../src/utils/pasuspender.c:92
#, c-format
msgid "execvp(): %s\n"
-msgstr ""
+msgstr "execvp(): %s\n"
#: ../src/utils/pasuspender.c:109
#, c-format
msgid "Failure to suspend: %s\n"
-msgstr ""
+msgstr "Suspend fehlgeschlagen: %s\n"
#: ../src/utils/pasuspender.c:124
#, c-format
msgid "Failure to resume: %s\n"
-msgstr ""
+msgstr "Resume fehlgeschlagen: %s\n"
#: ../src/utils/pasuspender.c:147
#, c-format
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 ""
+msgstr "SIGINT empfangen, beende.\n"
#: ../src/utils/pasuspender.c:194
#, c-format
msgid "WARNING: Child process terminated by signal %u\n"
-msgstr ""
+msgstr "WARNUNG: Kind-Prozess durch Signal %u beendet\n"
#: ../src/utils/pasuspender.c:212
-#, c-format
+#, fuzzy, c-format
msgid ""
"%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"
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"
+"\n"
#: ../src/utils/pasuspender.c:251
#, c-format
@@ -1264,7 +1407,7 @@ msgstr ""
#: ../src/utils/pactl.c:107
#, c-format
msgid "Failed to get statistics: %s\n"
-msgstr ""
+msgstr "Beziehen der Statistik fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:113
#, c-format
@@ -1279,12 +1422,12 @@ msgstr ""
#: ../src/utils/pactl.c:119
#, c-format
msgid "Sample cache size: %s\n"
-msgstr ""
+msgstr "Sample-Pufferspeichergrösse: %s\n"
#: ../src/utils/pactl.c:128
#, c-format
msgid "Failed to get server information: %s\n"
-msgstr ""
+msgstr "Beziehen der Server-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:135
#, c-format
@@ -1302,7 +1445,7 @@ msgstr ""
#: ../src/utils/pactl.c:160
#, c-format
msgid "Failed to get sink information: %s\n"
-msgstr ""
+msgstr "Erhalten der Sink-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:176
#, c-format
@@ -1321,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 ""
+msgstr "stumm"
#: ../src/utils/pactl.c:212
#, c-format
msgid "Failed to get source information: %s\n"
-msgstr ""
+msgstr "Beziehen der Quellen-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:228
#, c-format
@@ -1348,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 ""
+msgstr "k.A."
#: ../src/utils/pactl.c:263
#, c-format
msgid "Failed to get module information: %s\n"
-msgstr ""
+msgstr "Beziehen der Modul-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:281
#, c-format
@@ -1381,7 +1515,7 @@ msgstr ""
#: ../src/utils/pactl.c:298
#, c-format
msgid "Failed to get client information: %s\n"
-msgstr ""
+msgstr "Beziehen der Client-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:316
#, c-format
@@ -1441,7 +1575,7 @@ msgstr ""
#: ../src/utils/pactl.c:436
#, c-format
msgid "Failed to get sample information: %s\n"
-msgstr ""
+msgstr "Beziehen der Sample-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:455
#, c-format
@@ -1462,7 +1596,7 @@ msgstr ""
#: ../src/utils/pactl.c:481
#, c-format
msgid "Failed to get autoload information: %s\n"
-msgstr ""
+msgstr "Beziehen der Autoload-Information fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:497
#, c-format
@@ -1480,26 +1614,25 @@ msgstr ""
#: ../src/utils/pactl.c:504
msgid "source"
-msgstr ""
+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 ""
+msgstr "Fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:545
#, c-format
msgid "Failed to upload sample: %s\n"
-msgstr ""
+msgstr "Hochladen des Sample fehlgeschlagen: %s\n"
#: ../src/utils/pactl.c:562
#, c-format
msgid "Premature end of file\n"
-msgstr ""
+msgstr "Dateiende ist zu früh aufgetreten\n"
#: ../src/utils/pactl.c:678
-#, c-format
+#, fuzzy, c-format
msgid ""
"%s [options] stat\n"
"%s [options] list\n"
@@ -1517,9 +1650,31 @@ 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"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -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"
#: ../src/utils/pactl.c:729
#, c-format
@@ -1528,6 +1683,9 @@ msgid ""
"Compiled with libpulse %s\n"
"Linked with libpulse %s\n"
msgstr ""
+"pactl %s\n"
+"Kompiliert mit libpulse %s\n"
+"Gelinkt mit libpulse %s\n"
#: ../src/utils/pactl.c:768
#, c-format
@@ -1537,17 +1695,17 @@ msgstr ""
#: ../src/utils/pactl.c:790
#, c-format
msgid "Failed to open sound file.\n"
-msgstr ""
+msgstr "Öffnen der Audio-Datei fehlgeschlagen.\n"
#: ../src/utils/pactl.c:802
#, c-format
msgid "You have to specify a sample name to play\n"
-msgstr ""
+msgstr "You have to specify a sample name to play\n"
#: ../src/utils/pactl.c:814
#, c-format
msgid "You have to specify a sample name to remove\n"
-msgstr ""
+msgstr "You have to specify a sample name to remove\n"
#: ../src/utils/pactl.c:822
#, c-format
@@ -1562,53 +1720,65 @@ msgstr ""
#: ../src/utils/pactl.c:845
#, c-format
msgid "You have to specify a module name and arguments.\n"
-msgstr ""
+msgstr "You have to specify a module name and arguments.\n"
#: ../src/utils/pactl.c:865
#, c-format
msgid "You have to specify a module index\n"
-msgstr ""
+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
#, c-format
msgid "No valid command specified.\n"
-msgstr ""
+msgstr "Keinen gültigen Befehl angegeben.\n"
#: ../src/utils/pax11publish.c:61
-#, c-format
+#, fuzzy, c-format
msgid ""
"%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"
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"
+" -r Remove PulseAudio data from X11 display\n"
#: ../src/utils/pax11publish.c:94
#, c-format
msgid "Failed to parse command line.\n"
-msgstr ""
+msgstr "Parsen der Kommandozeile fehlgeschlagen.\n"
#: ../src/utils/pax11publish.c:108
#, c-format
msgid "Server: %s\n"
-msgstr ""
+msgstr "Server: %s\n"
#: ../src/utils/pax11publish.c:110
#, c-format
msgid "Source: %s\n"
-msgstr ""
+msgstr "Quelle: %s\n"
#: ../src/utils/pax11publish.c:112
#, c-format
@@ -1618,95 +1788,93 @@ msgstr ""
#: ../src/utils/pax11publish.c:114
#, c-format
msgid "Cookie: %s\n"
-msgstr ""
+msgstr "Cookie: %s\n"
#: ../src/utils/pax11publish.c:132
#, c-format
msgid "Failed to parse cookie data\n"
-msgstr ""
+msgstr "Paresen der Cookie-Daten fehlgeschlagen.\n"
#: ../src/utils/pax11publish.c:137
#, c-format
msgid "Failed to save cookie data\n"
-msgstr ""
+msgstr "Speichern der Cookie-Daten fehlgeschlagen\n"
#: ../src/utils/pax11publish.c:152
#, c-format
msgid "Failed to load client configuration file.\n"
-msgstr ""
+msgstr "Laden der Client-Konfigurationsdatei fehlgeschlagen.\n"
#: ../src/utils/pax11publish.c:157
#, c-format
msgid "Failed to read environment configuration data.\n"
-msgstr ""
+msgstr "Lesen the Umgebungsdaten fehlgeschlagen.\n"
#: ../src/utils/pax11publish.c:174
#, c-format
msgid "Failed to get FQDN.\n"
-msgstr ""
+msgstr "Beziehen des FQDN fehlgeschlagen.\n"
#: ../src/utils/pax11publish.c:194
#, c-format
msgid "Failed to load cookie data\n"
-msgstr ""
+msgstr "Laden der Cookie-Daten fehlgeschlagen\n"
#: ../src/utils/pax11publish.c:211
#, c-format
msgid "Not yet implemented.\n"
-msgstr ""
+msgstr "Noch nicht implementiert.\n"
#: ../src/utils/pacmd.c:64
#, c-format
msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
-msgstr ""
+msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
#: ../src/utils/pacmd.c:81
#, c-format
msgid "connect(): %s"
-msgstr ""
+msgstr "connect(): %s"
#: ../src/utils/pacmd.c:89
msgid "Failed to kill PulseAudio daemon."
-msgstr ""
+msgstr "Terminieren des PulseAudio-Daemon fehlgeschlagen."
#: ../src/utils/pacmd.c:97
msgid "Daemon not responding."
-msgstr ""
+msgstr "Daemon antwortet nicht."
#: ../src/utils/pacmd.c:112
#, c-format
msgid "select(): %s"
-msgstr ""
+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 ""
+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 ""
+msgstr "write(): %s"
#: ../src/utils/paplay.c:139
#, c-format
msgid "Stream successfully created\n"
-msgstr ""
+msgstr "Stream erfolgreich erzeugt\n"
#: ../src/utils/paplay.c:144
#, c-format
msgid "Stream errror: %s\n"
-msgstr ""
+msgstr "Stream-Fehler: %s\n"
#: ../src/utils/paplay.c:165
#, c-format
msgid "Connection established.\n"
-msgstr ""
+msgstr "Verbindung hergestellt.\n"
#: ../src/utils/paplay.c:198
-#, c-format
+#, fuzzy, c-format
msgid ""
"%s [options] [FILE]\n"
"\n"
@@ -1715,13 +1883,34 @@ 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"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -v, --verbose Enable verbose operation\n"
+"\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"
+" --channel-map=CHANNELMAP Set the channel map to the use\n"
#: ../src/utils/paplay.c:255
#, c-format
@@ -1730,24 +1919,33 @@ msgid ""
"Compiled with libpulse %s\n"
"Linked with libpulse %s\n"
msgstr ""
+"paplay %s\n"
+"Kompliert mit libpulse %s\n"
+"Gelinkt mit libpulse %s\n"
#: ../src/utils/paplay.c:292
#, c-format
msgid "Invalid channel map\n"
-msgstr ""
+msgstr "Ungültige Kanal-Zuweisung\n"
#: ../src/utils/paplay.c:314
#, c-format
msgid "Failed to open file '%s'\n"
-msgstr ""
+msgstr "Öffnen der Datei '%s' fehlgeschlagen\n"
#: ../src/utils/paplay.c:350
#, c-format
msgid "Channel map doesn't match file.\n"
-msgstr ""
+msgstr "Kanal-Zuweisung stimmt mit Datei nicht überein.\n"
#: ../src/utils/paplay.c:376
#, c-format
msgid "Using sample spec '%s'\n"
-msgstr ""
+msgstr "Sampling-Spezifikation '%s' wird benutzt\n"
+
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
+msgid "Cannot access autospawn lock."
+msgstr "Fehler beim Zugriff auf Autostart -Sperre."
+#~ msgid "socketpair(): %s"
+#~ msgstr "socketpair(): %s"
diff --git a/po/el.po b/po/el.po
new file mode 100644
index 00000000..79ccda73
--- /dev/null
+++ b/po/el.po
@@ -0,0 +1,1824 @@
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Dimitris Glezos <dimitris@glezos.com>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: el\n"
+"Report-Msgid-Bugs-To: \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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KAider 0.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
+msgid "Failed to add bind-now-loader."
+msgstr ""
+
+#: ../src/daemon/ltdl-bind-now.c:184
+msgid "Failed to find original dlopen loader."
+msgstr ""
+
+#: ../src/daemon/polkit.c:55
+#, c-format
+msgid "Cannot connect to system bus: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:65
+#, c-format
+msgid "Cannot get caller from PID: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:77
+msgid "Cannot set UID on caller object."
+msgstr ""
+
+#: ../src/daemon/polkit.c:82
+msgid "Failed to get CK session."
+msgstr ""
+
+#: ../src/daemon/polkit.c:90
+msgid "Cannot set UID on session object."
+msgstr ""
+
+#: ../src/daemon/polkit.c:95
+msgid "Cannot allocate PolKitAction."
+msgstr ""
+
+#: ../src/daemon/polkit.c:100
+msgid "Cannot set action_id"
+msgstr ""
+
+#: ../src/daemon/polkit.c:105
+msgid "Cannot allocate PolKitContext."
+msgstr ""
+
+#: ../src/daemon/polkit.c:110
+#, c-format
+msgid "Cannot initialize PolKitContext: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:119
+#, c-format
+msgid "Could not determine whether caller is authorized: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:139
+#, c-format
+msgid "Cannot obtain auth: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:148
+#, c-format
+msgid "PolicyKit responded with '%s'"
+msgstr ""
+
+#: ../src/daemon/main.c:134
+#, c-format
+msgid "Got signal %s."
+msgstr ""
+
+#: ../src/daemon/main.c:161
+msgid "Exiting."
+msgstr "Έξοδος."
+
+#: ../src/daemon/main.c:179
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Αποτυχία εύρεσης χρήστη '%s'."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Αποτυχία εύρεσης ομάδας χρηστών '%s'."
+
+#: ../src/daemon/main.c:188
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr ""
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr ""
+
+#: ../src/daemon/main.c:198
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr ""
+
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr ""
+
+#: ../src/daemon/main.c:213
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:229
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:245
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:259
+msgid "Successfully dropped root privileges."
+msgstr ""
+
+#: ../src/daemon/main.c:267
+msgid "System wide mode unsupported on this platform."
+msgstr ""
+
+#: ../src/daemon/main.c:285
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:425
+msgid "Failed to parse command line."
+msgstr ""
+
+#: ../src/daemon/main.c:441
+#, c-format
+msgid "We're in the group '%s', allowing high-priority scheduling."
+msgstr ""
+
+#: ../src/daemon/main.c:448
+#, c-format
+msgid "We're in the group '%s', allowing real-time scheduling."
+msgstr ""
+
+#: ../src/daemon/main.c:456
+msgid "PolicyKit grants us acquire-high-priority privilege."
+msgstr ""
+
+#: ../src/daemon/main.c:459
+msgid "PolicyKit refuses acquire-high-priority privilege."
+msgstr ""
+
+#: ../src/daemon/main.c:464
+msgid "PolicyKit grants us acquire-real-time privilege."
+msgstr ""
+
+#: ../src/daemon/main.c:467
+msgid "PolicyKit refuses acquire-real-time privilege."
+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"
+"We are not in group '"
+msgstr ""
+
+#: ../src/daemon/main.c:497
+msgid ""
+"High-priority scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+
+#: ../src/daemon/main.c:522
+msgid "Successfully increased RLIMIT_RTPRIO"
+msgstr ""
+
+#: ../src/daemon/main.c:525
+#, c-format
+msgid "RLIMIT_RTPRIO failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:532
+msgid "Giving up CAP_NICE"
+msgstr ""
+
+#: ../src/daemon/main.c:539
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+
+#: ../src/daemon/main.c:597
+msgid "Daemon not running"
+msgstr ""
+
+#: ../src/daemon/main.c:599
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr ""
+
+#: ../src/daemon/main.c:609
+#, c-format
+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 ""
+
+#: ../src/daemon/main.c:629
+msgid "Root priviliges required."
+msgstr ""
+
+#: ../src/daemon/main.c:634
+msgid "--start not supported for system instances."
+msgstr ""
+
+#: ../src/daemon/main.c:639
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:642
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:645
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr ""
+
+#: ../src/daemon/main.c:650
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+
+#: ../src/daemon/main.c:677
+msgid "Failed to acquire stdio."
+msgstr ""
+
+#: ../src/daemon/main.c:683
+#, c-format
+msgid "pipe failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:688
+#, c-format
+msgid "fork() failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:702
+#, c-format
+msgid "read() failed: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:708
+msgid "Daemon startup failed."
+msgstr ""
+
+#: ../src/daemon/main.c:710
+msgid "Daemon startup successful."
+msgstr ""
+
+#: ../src/daemon/main.c:780
+#, c-format
+msgid "This is PulseAudio %s"
+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: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:808
+#, c-format
+msgid "Machine ID is %s."
+msgstr ""
+
+#: ../src/daemon/main.c:813
+#, c-format
+msgid "Using runtime directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:818
+#, c-format
+msgid "Using state directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:821
+#, c-format
+msgid "Running in system mode: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:836
+msgid "pa_pid_file_create() failed."
+msgstr ""
+
+#: ../src/daemon/main.c:848
+msgid "Fresh high-resolution timers available! Bon appetit!"
+msgstr ""
+
+#: ../src/daemon/main.c:850
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Δικέ μου, ο πυρήνας σου είναι για τα μπάζα! Η πρόταση του σεφ σήμερα είναι "
+"Linux με ενεργοποιημένα τα high-resolution timers!"
+
+#: ../src/daemon/main.c:860
+msgid "pa_core_new() failed."
+msgstr ""
+
+#: ../src/daemon/main.c:921
+msgid "Failed to initialize daemon."
+msgstr ""
+
+#: ../src/daemon/main.c:926
+msgid "Daemon startup without any loaded modules, refusing to work."
+msgstr ""
+
+#: ../src/daemon/main.c:931
+#, c-format
+msgid "Default sink name (%s) does not exist in name register."
+msgstr ""
+
+#: ../src/daemon/main.c:944
+msgid "Daemon startup complete."
+msgstr ""
+
+#: ../src/daemon/main.c:950
+msgid "Daemon shutdown initiated."
+msgstr ""
+
+#: ../src/daemon/main.c:971
+msgid "Daemon terminated."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:117
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"COMMANDS:\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+" --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"
+" -k --kill Kill a running daemon\n"
+" --check Check for a running daemon\n"
+"\n"
+"OPTIONS:\n"
+" --system[=BOOL] Run as system-wide instance\n"
+" -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"
+" with elevated RLIMIT_NICE)\n"
+" --realtime[=BOOL] Try to enable realtime scheduling\n"
+" (only available as root, when SUID "
+"or\n"
+" with elevated RLIMIT_RTPRIO)\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"
+" time passed\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"
+" 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"
+" objects (plugins)\n"
+" --resample-method=METHOD Use the specified resampling method\n"
+" (See --dump-resample-methods for\n"
+" possible values)\n"
+" --use-pid-file[=BOOL] Create a PID file\n"
+" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
+" platforms that support it.\n"
+" --disable-shm[=BOOL] Disable shared memory support.\n"
+"\n"
+"STARTUP SCRIPT:\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"
+" after startup\n"
+"\n"
+" -n Don't load default script file\n"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:245
+msgid "--daemonize expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:252
+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)."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:274
+msgid "--high-priority expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:281
+msgid "--realtime expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:288
+msgid "--disallow-module-loading expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:295
+msgid "--disallow-exit boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:302
+msgid "--use-pid-file expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:319
+msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:338
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:345
+msgid "--system expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:352
+msgid "--no-cpu-limit expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:359
+msgid "--disable-shm expects boolean argument"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:60
+#, c-format
+msgid "Name: %s\n"
+msgstr "Όνομα: %s\n"
+
+#: ../src/daemon/dumpmodules.c:63
+#, c-format
+msgid "No module information available\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:66
+#, c-format
+msgid "Version: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:68
+#, c-format
+msgid "Description: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:70
+#, c-format
+msgid "Author: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Usage: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:73
+#, c-format
+msgid "Load Once: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:77
+#, c-format
+msgid "Path: %s\n"
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:205
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:221
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:237
+#, c-format
+msgid "[%s:%u] Invalid resample method '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:260
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:267
+#, c-format
+msgid "[%s:%u] rlimit not supported on this platform."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:283
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:301
+#, c-format
+msgid "[%s:%u] Invalid sample rate '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:319
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:337
+#, c-format
+msgid "[%s:%u] Invalid number of fragments '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:355
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:373
+#, c-format
+msgid "[%s:%u] Invalid nice level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:570
+#, c-format
+msgid "Failed to open configuration file: %s"
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:644
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr ""
+
+#: ../src/daemon/caps.c:63
+msgid "Dropping root priviliges."
+msgstr ""
+
+#: ../src/daemon/caps.c:103
+msgid "Limited capabilities successfully to CAP_SYS_NICE."
+msgstr ""
+
+#: ../src/pulse/channelmap.c:102
+msgid "Mono"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:104
+msgid "Front Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:105
+msgid "Front Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:106
+msgid "Front Right"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:108
+msgid "Rear Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:109
+msgid "Rear Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:110
+msgid "Rear Right"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:112
+msgid "Low Frequency Emmiter"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:114
+msgid "Front Left-of-center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:115
+msgid "Front Right-of-center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:117
+msgid "Side Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:118
+msgid "Side Right"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:120
+msgid "Auxiliary 0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:121
+msgid "Auxiliary 1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:122
+msgid "Auxiliary 2"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 3"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 4"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 5"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 6"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 7"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 8"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 9"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 10"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 11"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 12"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 13"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 14"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 15"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 16"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 17"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 18"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 19"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 20"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 21"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 22"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 23"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 24"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 25"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 26"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 27"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 28"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 29"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 30"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 31"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:153
+msgid "Top Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:155
+msgid "Top Front Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Front Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:157
+msgid "Top Front Right"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Rear Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Rear Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:161
+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 ""
+
+#: ../src/pulse/error.c:44
+msgid "Access denied"
+msgstr ""
+
+#: ../src/pulse/error.c:45
+msgid "Unknown command"
+msgstr ""
+
+#: ../src/pulse/error.c:46
+msgid "Invalid argument"
+msgstr ""
+
+#: ../src/pulse/error.c:47
+msgid "Entity exists"
+msgstr ""
+
+#: ../src/pulse/error.c:48
+msgid "No such entity"
+msgstr ""
+
+#: ../src/pulse/error.c:49
+msgid "Connection refused"
+msgstr ""
+
+#: ../src/pulse/error.c:50
+msgid "Protocol error"
+msgstr ""
+
+#: ../src/pulse/error.c:51
+msgid "Timeout"
+msgstr ""
+
+#: ../src/pulse/error.c:52
+msgid "No authorization key"
+msgstr ""
+
+#: ../src/pulse/error.c:53
+msgid "Internal error"
+msgstr ""
+
+#: ../src/pulse/error.c:54
+msgid "Connection terminated"
+msgstr ""
+
+#: ../src/pulse/error.c:55
+msgid "Entity killed"
+msgstr ""
+
+#: ../src/pulse/error.c:56
+msgid "Invalid server"
+msgstr ""
+
+#: ../src/pulse/error.c:57
+msgid "Module initalization failed"
+msgstr ""
+
+#: ../src/pulse/error.c:58
+msgid "Bad state"
+msgstr ""
+
+#: ../src/pulse/error.c:59
+msgid "No data"
+msgstr ""
+
+#: ../src/pulse/error.c:60
+msgid "Incompatible protocol version"
+msgstr ""
+
+#: ../src/pulse/error.c:61
+msgid "Too large"
+msgstr ""
+
+#: ../src/pulse/error.c:62
+msgid "Not supported"
+msgstr ""
+
+#: ../src/pulse/error.c:63
+msgid "Unknown error code"
+msgstr ""
+
+#: ../src/pulse/error.c:64
+msgid "No such extension"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
+msgid "XOpenDisplay() failed"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:78
+msgid "Failed to parse cookie data"
+msgstr ""
+
+#: ../src/pulse/client-conf.c:120
+#, c-format
+msgid "Failed to open configuration file '%s': %s"
+msgstr ""
+
+#: ../src/pulse/context.c:516
+msgid "No cookie loaded. Attempting to connect without."
+msgstr ""
+
+#: ../src/pulse/context.c:642
+#, c-format
+msgid "fork(): %s"
+msgstr ""
+
+#: ../src/pulse/context.c:695
+#, c-format
+msgid "waitpid(): %s"
+msgstr ""
+
+#: ../src/pulse/context.c:1256
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:93
+#, c-format
+msgid "pa_stream_write() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:132
+#, c-format
+msgid "pa_stream_peek() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "Buffer overrun, dropping incoming data\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:143
+#, c-format
+msgid "pa_stream_drop() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:169
+#, c-format
+msgid "Stream successfully created.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:172
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:176
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:179
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:183
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:187
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended).\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:197
+#, c-format
+msgid "Stream error: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:207
+#, c-format
+msgid "Stream device suspended.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:209
+#, c-format
+msgid "Stream device resumed.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:217
+#, c-format
+msgid "Stream underrun.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:224
+#, c-format
+msgid "Stream overrun.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:231
+#, c-format
+msgid "Stream started.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:238
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:238
+msgid "not "
+msgstr ""
+
+#: ../src/utils/pacat.c:259
+#, c-format
+msgid "Connection established.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:262
+#, c-format
+msgid "pa_stream_new() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:287
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:293
+#, c-format
+msgid "pa_stream_connect_record() failed: %s\n"
+msgstr ""
+
+#: ../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 ""
+
+#: ../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
+#, c-format
+msgid "Playback stream drained.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
+#, c-format
+msgid "Draining connection to server.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:369
+#, c-format
+msgid "Got EOF.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:375
+#, c-format
+msgid "pa_stream_drain(): %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:385
+#, c-format
+msgid "read() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:417
+#, c-format
+msgid "write() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:438
+#, c-format
+msgid "Got signal, exiting.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:452
+#, c-format
+msgid "Failed to get latency: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:457
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec. \r"
+msgstr ""
+
+#: ../src/utils/pacat.c:477
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:490
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -r, --record Create a connection for recording\n"
+" -p, --playback Create a connection for playback\n"
+"\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"
+" (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"
+" being connected to.\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"
+" --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"
+msgstr ""
+
+#: ../src/utils/pacat.c:591
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:647
+#, c-format
+msgid "Invalid channel map '%s'\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:676
+#, c-format
+msgid "Invalid latency specification '%s'\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:683
+#, c-format
+msgid "Invalid process time specification '%s'\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:694
+#, c-format
+msgid "Invalid sample specification\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:699
+#, c-format
+msgid "Channel map doesn't match sample specification\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:706
+#, c-format
+msgid "Opening a %s stream with sample specification '%s'.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:706
+msgid "recording"
+msgstr ""
+
+#: ../src/utils/pacat.c:706
+msgid "playback"
+msgstr ""
+
+#: ../src/utils/pacat.c:714
+#, c-format
+msgid "open(): %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:719
+#, c-format
+msgid "dup2(): %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:729
+#, c-format
+msgid "Too many arguments.\n"
+msgstr ""
+
+#: ../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 ""
+
+#: ../src/utils/pacat.c:763
+#, c-format
+msgid "io_new() failed.\n"
+msgstr ""
+
+#: ../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 ""
+
+#: ../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: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 ""
+
+#: ../src/utils/pasuspender.c:81
+#, c-format
+msgid "fork(): %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:92
+#, c-format
+msgid "execvp(): %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:109
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:124
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:147
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
+#: ../src/utils/paplay.c:191
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:194
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:212
+#, c-format
+msgid ""
+"%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"
+"\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:251
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:107
+#, c-format
+msgid "Failed to get statistics: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:113
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:116
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:119
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:128
+#, c-format
+msgid "Failed to get server information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:135
+#, c-format
+msgid ""
+"User name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %08x\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:160
+#, c-format
+msgid "Failed to get sink information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"*** Sink #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor Source: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
+msgid "muted"
+msgstr ""
+
+#: ../src/utils/pactl.c:212
+#, c-format
+msgid "Failed to get source information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:228
+#, c-format
+msgid ""
+"*** Source #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor of Sink: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%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
+msgid "n/a"
+msgstr ""
+
+#: ../src/utils/pactl.c:263
+#, c-format
+msgid "Failed to get module information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:281
+#, c-format
+msgid ""
+"*** Module #%u ***\n"
+"Name: %s\n"
+"Argument: %s\n"
+"Usage counter: %s\n"
+"Auto unload: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:298
+#, c-format
+msgid "Failed to get client information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:316
+#, c-format
+msgid ""
+"*** Client #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:333
+#, c-format
+msgid "Failed to get sink input information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:352
+#, c-format
+msgid ""
+"*** Sink Input #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Sink: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Volume: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Sink Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:385
+#, c-format
+msgid "Failed to get source output information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:405
+#, c-format
+msgid ""
+"*** Source Output #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Source: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Source Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:436
+#, c-format
+msgid "Failed to get sample information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:455
+#, c-format
+msgid ""
+"*** Sample #%u ***\n"
+"Name: %s\n"
+"Volume: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Duration: %0.1fs\n"
+"Size: %s\n"
+"Lazy: %s\n"
+"Filename: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:481
+#, c-format
+msgid "Failed to get autoload information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:497
+#, c-format
+msgid ""
+"*** Autoload Entry #%u ***\n"
+"Name: %s\n"
+"Type: %s\n"
+"Module: %s\n"
+"Argument: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:504
+msgid "sink"
+msgstr ""
+
+#: ../src/utils/pactl.c:504
+msgid "source"
+msgstr ""
+
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
+#, c-format
+msgid "Failure: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:545
+#, c-format
+msgid "Failed to upload sample: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid "Premature end of file\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:678
+#, c-format
+msgid ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -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"
+msgstr ""
+
+#: ../src/utils/pactl.c:729
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:768
+#, c-format
+msgid "Please specify a sample file to load\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:790
+#, c-format
+msgid "Failed to open sound file.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:802
+#, c-format
+msgid "You have to specify a sample name to play\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:814
+#, c-format
+msgid "You have to specify a sample name to remove\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:822
+#, c-format
+msgid "You have to specify a sink input index and a sink\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:831
+#, c-format
+msgid "You have to specify a source output index and a source\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:845
+#, c-format
+msgid "You have to specify a module name and arguments.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:865
+#, c-format
+msgid "You have to specify a module index\n"
+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"
+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"
+msgstr ""
+
+#: ../src/utils/pactl.c:904
+#, c-format
+msgid "No valid command specified.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%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"
+" -r Remove PulseAudio data from X11 display\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:108
+#, c-format
+msgid "Server: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:110
+#, c-format
+msgid "Source: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:112
+#, c-format
+msgid "Sink: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:114
+#, c-format
+msgid "Cookie: %s\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:132
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:152
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:174
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:194
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:211
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr ""
+
+#: ../src/utils/pacmd.c:64
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:81
+#, c-format
+msgid "connect(): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:89
+msgid "Failed to kill PulseAudio daemon."
+msgstr ""
+
+#: ../src/utils/pacmd.c:97
+msgid "Daemon not responding."
+msgstr ""
+
+#: ../src/utils/pacmd.c:112
+#, c-format
+msgid "select(): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:124 ../src/utils/pacmd.c:140
+#, c-format
+msgid "read(): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:153 ../src/utils/pacmd.c:167
+#, c-format
+msgid "write(): %s"
+msgstr ""
+
+#: ../src/utils/paplay.c:139
+#, c-format
+msgid "Stream successfully created\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:144
+#, c-format
+msgid "Stream errror: %s\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:165
+#, c-format
+msgid "Connection established.\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:198
+#, c-format
+msgid ""
+"%s [options] [FILE]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -v, --verbose Enable verbose operation\n"
+"\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"
+" --channel-map=CHANNELMAP Set the channel map to the use\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:255
+#, c-format
+msgid ""
+"paplay %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:292
+#, c-format
+msgid "Invalid channel map\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:314
+#, c-format
+msgid "Failed to open file '%s'\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:350
+#, c-format
+msgid "Channel map doesn't match file.\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:376
+#, c-format
+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
new file mode 100644
index 00000000..6d35390a
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,2178 @@
+# French translation of pulseaudio.
+# Copyright (C) 2006-2008 Lennart Poettering
+# This file is distributed under the same license as the pulseaudio package.
+#
+# Robert-André Mauchin <zebob.m@pengzone.org>, 2008.
+# Michaël Ughetto <telimektar esraonline com>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pulseaudio trunk\n"
+"Report-Msgid-Bugs-To: \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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n>1;\n"
+
+#: ../src/daemon/ltdl-bind-now.c:177 ../src/daemon/ltdl-bind-now.c:197
+msgid "Failed to add bind-now-loader."
+msgstr "Échec lors de l'ajout du chargeur bind-now."
+
+#: ../src/daemon/ltdl-bind-now.c:184
+msgid "Failed to find original dlopen loader."
+msgstr "Échec lors de la recherche du chargeur dlopen original."
+
+#: ../src/daemon/polkit.c:55
+#, c-format
+msgid "Cannot connect to system bus: %s"
+msgstr "Impossible de se connecter au bus système : %s"
+
+#: ../src/daemon/polkit.c:65
+#, c-format
+msgid "Cannot get caller from PID: %s"
+msgstr "Impossible d'obtenir le programme appelant à partir du PID : %s"
+
+#: ../src/daemon/polkit.c:77
+msgid "Cannot set UID on caller object."
+msgstr "Impossible de définir un UID sur l'objet appelant."
+
+#: ../src/daemon/polkit.c:82
+msgid "Failed to get CK session."
+msgstr "Échec lors de l'obtention de la session CK."
+
+#: ../src/daemon/polkit.c:90
+msgid "Cannot set UID on session object."
+msgstr "Impossible de définir l'UID sur l'objet de session."
+
+#: ../src/daemon/polkit.c:95
+msgid "Cannot allocate PolKitAction."
+msgstr "Impossible d'allouer PolKitAction."
+
+#: ../src/daemon/polkit.c:100
+msgid "Cannot set action_id"
+msgstr "Impossible de définir action_id."
+
+#: ../src/daemon/polkit.c:105
+msgid "Cannot allocate PolKitContext."
+msgstr "Impossible d'allouer PolKitContext."
+
+#: ../src/daemon/polkit.c:110
+#, c-format
+msgid "Cannot initialize PolKitContext: %s"
+msgstr "Impossible d'initialiser PolKitContext : %s"
+
+#: ../src/daemon/polkit.c:119
+#, c-format
+msgid "Could not determine whether caller is authorized: %s"
+msgstr "Impossible de déterminer si le programme appelant est autorisé : %s"
+
+#: ../src/daemon/polkit.c:139
+#, c-format
+msgid "Cannot obtain auth: %s"
+msgstr "Impossible d'obtenir l'authentification : %s"
+
+#: ../src/daemon/polkit.c:148
+#, c-format
+msgid "PolicyKit responded with '%s'"
+msgstr "PolicyKit a renvoyé « %s »"
+
+#: ../src/daemon/main.c:134
+#, c-format
+msgid "Got signal %s."
+msgstr "Signal %s obtenu."
+
+#: ../src/daemon/main.c:161
+msgid "Exiting."
+msgstr "Fermeture."
+
+#: ../src/daemon/main.c:179
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Impossible de trouver l'utilisateur « %s »."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Impossible de trouver le groupe « %s »."
+
+#: ../src/daemon/main.c:188
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr "Utilisateur « %s ” (UID %lu) et groupe « %s » (GID %lu) trouvé."
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr ""
+"Le GID de l'utilisateur « %s » et du groupe « %s » ne sont pas identiques."
+
+#: ../src/daemon/main.c:198
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr "Le dossier personnel de l'utilisateur « %s » n'est pas « %s », ignoré."
+
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "Échec lors de la création de « %s » : %s"
+
+#: ../src/daemon/main.c:213
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr "Échec lors du changement de la liste du groupe : %s"
+
+#: ../src/daemon/main.c:229
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr "Échec lors du changement de GID : %s"
+
+#: ../src/daemon/main.c:245
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr "Échec lors du changement d'UID : %s"
+
+#: ../src/daemon/main.c:259
+msgid "Successfully dropped root privileges."
+msgstr "Les permissions root ont été correctement abandonnées."
+
+#: ../src/daemon/main.c:267
+msgid "System wide mode unsupported on this platform."
+msgstr "Mode système étendu non pris en charge sur cette plateforme."
+
+#: ../src/daemon/main.c:285
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) a échoué : %s"
+
+#: ../src/daemon/main.c:425
+msgid "Failed to parse command line."
+msgstr "Échec lors de l'analyse de la ligne de commande"
+
+#: ../src/daemon/main.c:441
+#, c-format
+msgid "We're in the group '%s', allowing high-priority scheduling."
+msgstr ""
+"Nous sommes dans le groupe « %s », permettant une planification à haute "
+"priorité."
+
+#: ../src/daemon/main.c:448
+#, c-format
+msgid "We're in the group '%s', allowing real-time scheduling."
+msgstr ""
+"Nous sommes dans le groupe « %s », permettant une planification en temps réel."
+
+#: ../src/daemon/main.c:456
+msgid "PolicyKit grants us acquire-high-priority privilege."
+msgstr "PolicyKit a accordé l'acquisition des permissions de haute priorité."
+
+#: ../src/daemon/main.c:459
+msgid "PolicyKit refuses acquire-high-priority privilege."
+msgstr "PolicyKit a refusé l'acquisition des permissions de haute priorité."
+
+#: ../src/daemon/main.c:464
+msgid "PolicyKit grants us acquire-real-time privilege."
+msgstr "PolicyKit a accordé l'acquisition des permissions de temps réel."
+
+#: ../src/daemon/main.c:467
+msgid "PolicyKit refuses acquire-real-time privilege."
+msgstr "PolicyKit a refusé l'acquisition des permissions de temps réel."
+
+#: ../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"
+"We are not in group '"
+msgstr ""
+"Le SUID root a été appelé et la planification à haute priorité/en temps réel "
+"demandée dans la configuration. Néanmoins nous n'avons pas les permissions "
+"nécessaires :\n"
+"nous ne somme pas dans le groupe "
+
+#: ../src/daemon/main.c:497
+msgid ""
+"High-priority scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+"La planification à haute priorité est activée dans la configuration mais "
+"n'est pas permise par la politique."
+
+#: ../src/daemon/main.c:522
+msgid "Successfully increased RLIMIT_RTPRIO"
+msgstr "Augmentation de RLIMIT_RTPRIO réussie"
+
+#: ../src/daemon/main.c:525
+#, c-format
+msgid "RLIMIT_RTPRIO failed: %s"
+msgstr "RLIMIT_RTPRIO a échoué : %s"
+
+#: ../src/daemon/main.c:532
+msgid "Giving up CAP_NICE"
+msgstr "Abandon de CAP_NICE"
+
+#: ../src/daemon/main.c:539
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+"La planification en temps réel est activée mais n'est pas permise par la "
+"politique."
+
+#: ../src/daemon/main.c:597
+msgid "Daemon not running"
+msgstr "Lé démon n'est pas lancé"
+
+#: ../src/daemon/main.c:599
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr "Le démon est lancé avec le PID %u"
+
+#: ../src/daemon/main.c:609
+#, c-format
+msgid "Failed to kill daemon: %s"
+msgstr "Impossible de tuer le démon : %s"
+
+#: ../src/daemon/main.c:627
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Le programme n'est pas conçu pour être lancé en tant que root (sauf si --"
+"system est renseigné)."
+
+#: ../src/daemon/main.c:629
+msgid "Root priviliges required."
+msgstr "Les permissions root sont nécessaires."
+
+#: ../src/daemon/main.c:634
+msgid "--start not supported for system instances."
+msgstr "--start n'est pas pris en charge pour les instances système."
+
+#: ../src/daemon/main.c:639
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr ""
+"Le démon s'exécute en mode système, mais --disallow-exit n'est pas défini."
+
+#: ../src/daemon/main.c:642
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr ""
+"Le démon s'exécute en mode système, mais --disallow-module-loading n'est pas "
+"défini."
+
+#: ../src/daemon/main.c:645
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr "Le démon s'exécute en mode système, désactivation forcée du mode SHM."
+
+#: ../src/daemon/main.c:650
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+"Le démon s'exécute en mode système, désactivation forcée de la fermeture "
+"après délai d'inactivité."
+
+#: ../src/daemon/main.c:677
+msgid "Failed to acquire stdio."
+msgstr "Échec lors de l'acquisition de stdio."
+
+#: ../src/daemon/main.c:683
+#, c-format
+msgid "pipe failed: %s"
+msgstr "Échec du tube : %s"
+
+#: ../src/daemon/main.c:688
+#, c-format
+msgid "fork() failed: %s"
+msgstr "Échec de fork() : %s"
+
+#: ../src/daemon/main.c:702
+#, c-format
+msgid "read() failed: %s"
+msgstr "Échec de read() : %s"
+
+#: ../src/daemon/main.c:708
+msgid "Daemon startup failed."
+msgstr "Échec lors du démarrage du démon."
+
+#: ../src/daemon/main.c:710
+msgid "Daemon startup successful."
+msgstr "Démarrage du démon réussi."
+
+#: ../src/daemon/main.c:780
+#, c-format
+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: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:793
+msgid "Compiled with Valgrind support: no"
+msgstr "Compilé avec la prise en charge Valgrind : non"
+
+#: ../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:801
+msgid "Optimized build: no"
+msgstr "Construction optimisée : non"
+
+#: ../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:808
+#, c-format
+msgid "Machine ID is %s."
+msgstr "L'ID de la machine est %s."
+
+#: ../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:818
+#, c-format
+msgid "Using state directory %s."
+msgstr "Utilisation du répertoire d'état %s."
+
+#: ../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:836
+msgid "pa_pid_file_create() failed."
+msgstr "Échec de pa_pid_file_create()."
+
+#: ../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:850
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+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:860
+msgid "pa_core_new() failed."
+msgstr "Échec de pa_core_new()."
+
+#: ../src/daemon/main.c:921
+msgid "Failed to initialize daemon."
+msgstr "Échec lors de l'initialisation du démon"
+
+#: ../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: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:944
+msgid "Daemon startup complete."
+msgstr "Démarrage du démon effectué."
+
+#: ../src/daemon/main.c:950
+msgid "Daemon shutdown initiated."
+msgstr "Fermeture du démon initiée."
+
+#: ../src/daemon/main.c:971
+msgid "Daemon terminated."
+msgstr "Démon terminé."
+
+#: ../src/daemon/cmdline.c:117
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"COMMANDS:\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+" --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"
+" -k --kill Kill a running daemon\n"
+" --check Check for a running daemon\n"
+"\n"
+"OPTIONS:\n"
+" --system[=BOOL] Run as system-wide instance\n"
+" -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"
+" with elevated RLIMIT_NICE)\n"
+" --realtime[=BOOL] Try to enable realtime scheduling\n"
+" (only available as root, when SUID "
+"or\n"
+" with elevated RLIMIT_RTPRIO)\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"
+" time passed\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"
+" 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"
+" objects (plugins)\n"
+" --resample-method=METHOD Use the specified resampling method\n"
+" (See --dump-resample-methods for\n"
+" possible values)\n"
+" --use-pid-file[=BOOL] Create a PID file\n"
+" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
+" platforms that support it.\n"
+" --disable-shm[=BOOL] Disable shared memory support.\n"
+"\n"
+"STARTUP SCRIPT:\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"
+" after startup\n"
+"\n"
+" -n Don't load default script file\n"
+msgstr ""
+"%s [options]\n"
+"\n"
+"COMMANDES :\n"
+" -h, --help Affiche cette aide\n"
+" --version Affiche la version\n"
+" --dump-conf Affiche la configuration par défaut\n"
+" --dump-modules Affiche la liste des modules "
+"disponibles\n"
+" --dump-resample-methods Affiche la liste des méthodes "
+"d'échantillonnage disponibles\n"
+" --cleanup-shm Nettoie les segments de mémoire "
+"partagée périmés\n"
+" --start Démarre le démon s'il n'est pas "
+"lancé\n"
+" -k --kill Tue un démon en cours d'exécution\n"
+" --check Vérifie s'il existe un démon en "
+"cours d'exécution\n"
+"\n"
+"OPTIONS :\n"
+" --system[=BOOL] Exécuter en tant qu'instance "
+"système\n"
+" -D, --daemonize[=BOOL] Définir en tant que démon après le "
+"démarrage\n"
+" --fail[=BOOL] Quitte quand le démarrage échoue\n"
+" --high-priority[=BOOL] Tente de définir un niveau nice plus "
+"élevé\n"
+" (seulement disponible en tant que "
+"root, avec le SUID ou\n"
+" avec un RLIMIT_NICE élevé)\n"
+" --realtime[=BOOL] Tente d'activer une planification en "
+"temps réel\n"
+" (seulement disponible en tant que "
+"root, avec le SUID ou\n"
+" ave un RLIMIT_RTPRIO élevé)\n"
+" --disallow-module-loading[=BOOL] Empêche les chargements/"
+"déchargements de module\n"
+" demandés par l'utilisateur après le "
+"démarrage\n"
+" --disallow-exit[=BOOL] Empêche les fermetures demandées par "
+"l'utilisateur\n"
+" --exit-idle-time=SECS Termine le démon quand la durée "
+"d'inactivité \n"
+" et ce temps se sont écoulés\n"
+" --module-idle-time=SECS Décharge les modules chargés "
+"automatiquement \n"
+" quand la durée d'inactivité et ce "
+"temps se sont écoulés\n"
+" --scache-idle-time=SECS Décharge les échantillons chargés "
+"automatiquement \n"
+" quand la durée d'inactivité et ce "
+"temps se sont écoulés\n"
+" --log-level[=NIVEAU] Augmente ou définit le niveau de "
+"verbosité\n"
+" -v Augmente le niveau de verbosité\n"
+" --log-target={auto,syslog,stderr} Indique la cible du journal\n"
+" -p, --dl-search-path=CHEMIN Définit le chemin de recherche pour "
+"les objets dynamiques\n"
+" partagés (extensions)\n"
+" --resample-method=MÉTHODE Utilise la méthode de "
+"rééchantillonnage indiquée\n"
+" (Voir --dump-resample-methods pour\n"
+" les valeurs possibles)\n"
+" --use-pid-file[=BOOL] Crée un fichier PID\n"
+" --no-cpu-limit[=BOOL] Ne pas installer de limiteur de "
+"charge CPU\n"
+" sur les plateformes qui le "
+"supportent.\n"
+" --disable-shm[=BOOL] Désactive la prise en charge de la "
+"mémoire partagée.\n"
+"\n"
+"SCRIPT DE DÉMARRAGE :\n"
+" -L, --load=\"PARAMÈTRES DU MODULE\" Charge le module d'extension indiqué "
+"avec\n"
+" le paramètre indiqué\n"
+" -F, --file=NOMDEFICHIER Exécute le script indiqué\n"
+" -C Ouvre une ligne de commande sur le "
+"TTY en cours \n"
+" après le démarrage\n"
+"\n"
+" -n Ne pas charger les fichiers de "
+"scripts par défaut\n"
+
+#: ../src/daemon/cmdline.c:245
+msgid "--daemonize expects boolean argument"
+msgstr "--daemonize requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:252
+msgid "--fail expects boolean argument"
+msgstr "--fail requiert un paramètre booléen"
+
+#: ../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 requiert un paramètre de niveau de journal (soit numérique entre "
+"0 et 4, soit de débogage : info, notice, warn , error)."
+
+#: ../src/daemon/cmdline.c:274
+msgid "--high-priority expects boolean argument"
+msgstr "--high-priority requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:281
+msgid "--realtime expects boolean argument"
+msgstr "--realtime requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:288
+msgid "--disallow-module-loading expects boolean argument"
+msgstr "--disallow-module-loading requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:295
+msgid "--disallow-exit boolean argument"
+msgstr "--disallow-exit requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:302
+msgid "--use-pid-file expects boolean argument"
+msgstr "--use-pid-file requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:319
+msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+msgstr "Cible du journal invalide : utilisez « syslog », « stderr » ou « auto »."
+
+#: ../src/daemon/cmdline.c:338
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr "Méthode de rééchantillonnage invalide « %s »."
+
+#: ../src/daemon/cmdline.c:345
+msgid "--system expects boolean argument"
+msgstr "--system requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:352
+msgid "--no-cpu-limit expects boolean argument"
+msgstr "--no-cpu-limit requiert un paramètre booléen"
+
+#: ../src/daemon/cmdline.c:359
+msgid "--disable-shm expects boolean argument"
+msgstr "--disable-shm requiert un paramètre booléen"
+
+#: ../src/daemon/dumpmodules.c:60
+#, c-format
+msgid "Name: %s\n"
+msgstr "Nom : %s\n"
+
+#: ../src/daemon/dumpmodules.c:63
+#, c-format
+msgid "No module information available\n"
+msgstr "Aucune information de module disponible\n"
+
+#: ../src/daemon/dumpmodules.c:66
+#, c-format
+msgid "Version: %s\n"
+msgstr "Version : %s\n"
+
+#: ../src/daemon/dumpmodules.c:68
+#, c-format
+msgid "Description: %s\n"
+msgstr "Description : %s\n"
+
+#: ../src/daemon/dumpmodules.c:70
+#, c-format
+msgid "Author: %s\n"
+msgstr "Auteur : %s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Usage: %s\n"
+msgstr "Utilisation : %s\n"
+
+#: ../src/daemon/dumpmodules.c:73
+#, c-format
+msgid "Load Once: %s\n"
+msgstr "Chargement unique : %s\n"
+
+#: ../src/daemon/dumpmodules.c:77
+#, c-format
+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:205
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr "[%s:%u] Cible du journal « %s » invalide."
+
+#: ../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: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:260
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr "[%s:%u] rlimit « %s » invalide."
+
+#: ../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:283
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr "[%s:%u] Format d'échantillon « %s » invalide."
+
+#: ../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:319
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr "[%s:%u] Canaux d'échantillonnage « %s » invalide."
+
+#: ../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:355
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr "[%s:%u] Taille du fragment « %s » invalide."
+
+#: ../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: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:644
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr "### Lecture à partir du fichier de configuration : %s ###\n"
+
+#: ../src/daemon/caps.c:63
+msgid "Dropping root priviliges."
+msgstr "Abandon des permissions root."
+
+#: ../src/daemon/caps.c:103
+msgid "Limited capabilities successfully to CAP_SYS_NICE."
+msgstr "Limitation des capacités à CAP_SYS_NICE réussie."
+
+#: ../src/pulse/channelmap.c:102
+msgid "Mono"
+msgstr "Mono"
+
+#: ../src/pulse/channelmap.c:104
+msgid "Front Center"
+msgstr "Avant centre"
+
+#: ../src/pulse/channelmap.c:105
+msgid "Front Left"
+msgstr "Avant gauche"
+
+#: ../src/pulse/channelmap.c:106
+msgid "Front Right"
+msgstr "Avant droit"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Rear Center"
+msgstr "Arrière centre"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Rear Left"
+msgstr "Arrière gauche"
+
+#: ../src/pulse/channelmap.c:110
+msgid "Rear Right"
+msgstr "Arrière droit"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Low Frequency Emmiter"
+msgstr "Émetteur à basse fréquence"
+
+#: ../src/pulse/channelmap.c:114
+msgid "Front Left-of-center"
+msgstr "Avant à gauche du centre"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Front Right-of-center"
+msgstr "Avant à droite du centre"
+
+#: ../src/pulse/channelmap.c:117
+msgid "Side Left"
+msgstr "Côté gauche"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Side Right"
+msgstr "Côté droit"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Auxiliary 0"
+msgstr "Auxiliaire 0"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Auxiliary 1"
+msgstr "Auxiliaire 1"
+
+#: ../src/pulse/channelmap.c:122
+msgid "Auxiliary 2"
+msgstr "Auxiliaire 2"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 3"
+msgstr "Auxiliaire 3"
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 4"
+msgstr "Auxiliaire 4"
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 5"
+msgstr "Auxiliaire 5"
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 6"
+msgstr "Auxiliaire 6"
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 7"
+msgstr "Auxiliaire 7"
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 8"
+msgstr "Auxiliaire 8"
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 9"
+msgstr "Auxiliaire 9"
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 10"
+msgstr "Auxiliaire 10"
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 11"
+msgstr "Auxiliaire 11"
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 12"
+msgstr "Auxiliaire 12"
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 13"
+msgstr "Auxiliaire 13"
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 14"
+msgstr "Auxiliaire 14"
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 15"
+msgstr "Auxiliaire 15"
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 16"
+msgstr "Auxiliaire 16"
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 17"
+msgstr "Auxiliaire 17"
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 18"
+msgstr "Auxiliaire 18"
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 19"
+msgstr "Auxiliaire 19"
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 20"
+msgstr "Auxiliaire 20"
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 21"
+msgstr "Auxiliaire 21"
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 22"
+msgstr "Auxiliaire 22"
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 23"
+msgstr "Auxiliaire 23"
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 24"
+msgstr "Auxiliaire 24"
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 25"
+msgstr "Auxiliaire 25"
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 26"
+msgstr "Auxiliaire 26"
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 27"
+msgstr "Auxiliaire 27"
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 28"
+msgstr "Auxiliaire 28"
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 29"
+msgstr "Auxiliaire 29"
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 30"
+msgstr "Auxiliaire 30"
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 31"
+msgstr "Auxiliaire 31"
+
+#: ../src/pulse/channelmap.c:153
+msgid "Top Center"
+msgstr "Centre haut"
+
+#: ../src/pulse/channelmap.c:155
+msgid "Top Front Center"
+msgstr "Avant centre haut"
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Front Left"
+msgstr "Avant gauche haut"
+
+#: ../src/pulse/channelmap.c:157
+msgid "Top Front Right"
+msgstr "Avant droit haut"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Rear Center"
+msgstr "Arrière centre haut"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Rear Left"
+msgstr "Arrière gauche haut"
+
+#: ../src/pulse/channelmap.c:161
+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"
+
+#: ../src/pulse/error.c:44
+msgid "Access denied"
+msgstr "Accès refusé"
+
+#: ../src/pulse/error.c:45
+msgid "Unknown command"
+msgstr "Commande inconnue"
+
+#: ../src/pulse/error.c:46
+msgid "Invalid argument"
+msgstr "Paramètre invalide"
+
+#: ../src/pulse/error.c:47
+msgid "Entity exists"
+msgstr "L'entité existe"
+
+#: ../src/pulse/error.c:48
+msgid "No such entity"
+msgstr "Aucune entité de ce type"
+
+#: ../src/pulse/error.c:49
+msgid "Connection refused"
+msgstr "Connexion refusée"
+
+#: ../src/pulse/error.c:50
+msgid "Protocol error"
+msgstr "Erreur du protocole"
+
+#: ../src/pulse/error.c:51
+msgid "Timeout"
+msgstr "Délai dépassé"
+
+#: ../src/pulse/error.c:52
+msgid "No authorization key"
+msgstr "Aucune clé d'autorisation"
+
+#: ../src/pulse/error.c:53
+msgid "Internal error"
+msgstr "Erreur interne"
+
+#: ../src/pulse/error.c:54
+msgid "Connection terminated"
+msgstr "Connexion terminée"
+
+#: ../src/pulse/error.c:55
+msgid "Entity killed"
+msgstr "L'entité a été tuée"
+
+#: ../src/pulse/error.c:56
+msgid "Invalid server"
+msgstr "Serveur invalide"
+
+#: ../src/pulse/error.c:57
+msgid "Module initalization failed"
+msgstr "Échec lors de l'initialisation du module"
+
+#: ../src/pulse/error.c:58
+msgid "Bad state"
+msgstr "État incorrect"
+
+#: ../src/pulse/error.c:59
+msgid "No data"
+msgstr "Aucune donnée"
+
+#: ../src/pulse/error.c:60
+msgid "Incompatible protocol version"
+msgstr "Version du protocole invalide"
+
+#: ../src/pulse/error.c:61
+msgid "Too large"
+msgstr "Trop grand"
+
+#: ../src/pulse/error.c:62
+msgid "Not supported"
+msgstr "Non pris en charge"
+
+#: ../src/pulse/error.c:63
+msgid "Unknown error code"
+msgstr "Code d'erreur inconnu"
+
+#: ../src/pulse/error.c:64
+msgid "No such extension"
+msgstr "Aucune extension de ce type"
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
+msgid "XOpenDisplay() failed"
+msgstr "Échec de XOpenDisplay()"
+
+#: ../src/pulse/client-conf-x11.c:78
+msgid "Failed to parse cookie data"
+msgstr "Échec lors de l'analyse des données du cookie"
+
+#: ../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:516
+msgid "No cookie loaded. Attempting to connect without."
+msgstr "Aucun cookie chargé. Tentative de connexion sans celui-ci."
+
+#: ../src/pulse/context.c:642
+#, c-format
+msgid "fork(): %s"
+msgstr "fork() : %s"
+
+#: ../src/pulse/context.c:695
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid() : %s"
+
+#: ../src/pulse/context.c:1256
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr "Message reçu pour une extension inconnue « %s »"
+
+#: ../src/utils/pacat.c:93
+#, c-format
+msgid "pa_stream_write() failed: %s\n"
+msgstr "Échec de pa_stream_write() : %s\n"
+
+#: ../src/utils/pacat.c:132
+#, c-format
+msgid "pa_stream_peek() failed: %s\n"
+msgstr "Échec de pa_stream_peek() : %s\n"
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "Buffer overrun, dropping incoming data\n"
+msgstr "Saturation du tampon, abandon des données entrantes\n"
+
+#: ../src/utils/pacat.c:143
+#, c-format
+msgid "pa_stream_drop() failed: %s\n"
+msgstr "Échec de pa_stream_drop() : %s\n"
+
+#: ../src/utils/pacat.c:169
+#, c-format
+msgid "Stream successfully created.\n"
+msgstr "Création du flux réussie.\n"
+
+#: ../src/utils/pacat.c:172
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s\n"
+msgstr "Échec de pa_stream_get_buffer_attr() : %s\n"
+
+#: ../src/utils/pacat.c:176
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+msgstr "Mesures du tampon : maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+
+#: ../src/utils/pacat.c:179
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u\n"
+msgstr "Mesures du tampon : maxlength=%u, fragsize=%u\n"
+
+#: ../src/utils/pacat.c:183
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'.\n"
+msgstr ""
+"Utilisation de la spécification d'échantillon « %s », plan des canaux « %s ».\n"
+
+# l'espace manquant entre %s et suspended est voulu
+#: ../src/utils/pacat.c:187
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended).\n"
+msgstr "Connecté au périphérique %s (%u, %ssuspendu).\n"
+
+#: ../src/utils/pacat.c:197
+#, c-format
+msgid "Stream error: %s\n"
+msgstr "Erreur du flux : %s\n"
+
+#: ../src/utils/pacat.c:207
+#, c-format
+msgid "Stream device suspended.%s \n"
+msgstr "Périphérique de flux suspendu %s \n"
+
+#: ../src/utils/pacat.c:209
+#, c-format
+msgid "Stream device resumed.%s \n"
+msgstr "Périphérique de flux repris %s \n"
+
+#: ../src/utils/pacat.c:217
+#, c-format
+msgid "Stream underrun.%s \n"
+msgstr "Flux vide %s \n"
+
+#: ../src/utils/pacat.c:224
+#, c-format
+msgid "Stream overrun.%s \n"
+msgstr "Flux saturé %s \n"
+
+#: ../src/utils/pacat.c:231
+#, c-format
+msgid "Stream started.%s \n"
+msgstr "Flux démarré %s \n"
+
+#: ../src/utils/pacat.c:238
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s \n"
+msgstr "Flux déplacé vers le périphérique %s (%u, %ssuspendu).%s \n"
+
+# suspendu ou non suspendu
+#: ../src/utils/pacat.c:238
+msgid "not "
+msgstr "non "
+
+#: ../src/utils/pacat.c:259
+#, c-format
+msgid "Connection established.%s \n"
+msgstr "Connection établie.%s \n"
+
+#: ../src/utils/pacat.c:262
+#, c-format
+msgid "pa_stream_new() failed: %s\n"
+msgstr "Échec de pa_stream_new() : %s\n"
+
+#: ../src/utils/pacat.c:287
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s\n"
+msgstr "Échec de pa_stream_connect_playback() : %s\n"
+
+#: ../src/utils/pacat.c:293
+#, c-format
+msgid "pa_stream_connect_record() failed: %s\n"
+msgstr "Échec de pa_stream_connect_record() : %s\n"
+
+#: ../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 "Échec lors de la connexion : %s\n"
+
+#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75
+#, c-format
+msgid "Failed to drain stream: %s\n"
+msgstr "Échec lors du vidage du flux : %s\n"
+
+#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80
+#, c-format
+msgid "Playback stream drained.\n"
+msgstr "Flux de lecture vidé.\n"
+
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
+#, c-format
+msgid "Draining connection to server.\n"
+msgstr "Vidage de la connexion au serveur.\n"
+
+#: ../src/utils/pacat.c:369
+#, c-format
+msgid "Got EOF.\n"
+msgstr "EOF obtenu.\n"
+
+#: ../src/utils/pacat.c:375
+#, c-format
+msgid "pa_stream_drain(): %s\n"
+msgstr "pa_stream_drain() : %s\n"
+
+#: ../src/utils/pacat.c:385
+#, c-format
+msgid "read() failed: %s\n"
+msgstr "Échec de read() : %s\n"
+
+#: ../src/utils/pacat.c:417
+#, c-format
+msgid "write() failed: %s\n"
+msgstr "Échec de write() : %s\n"
+
+#: ../src/utils/pacat.c:438
+#, c-format
+msgid "Got signal, exiting.\n"
+msgstr "Signal obtenu, fermeture.\n"
+
+#: ../src/utils/pacat.c:452
+#, c-format
+msgid "Failed to get latency: %s\n"
+msgstr "Échec lors de l'obtention de la latence : %s\n"
+
+#: ../src/utils/pacat.c:457
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec. \r"
+msgstr "Durée : %0.3f s ; Latency : %0.0f µs. \r"
+
+#: ../src/utils/pacat.c:477
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s\n"
+msgstr "Échec de pa_stream_update_timing_info() : %s\n"
+
+# downmix = par ex. convertir 5 canaux en 2 canaux
+# upmixer = par ex. convertir 2 canaux en 5 canaux
+# https://bugzilla.redhat.com/show_bug.cgi?id=460798
+#: ../src/utils/pacat.c:490
+#, fuzzy, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -r, --record Create a connection for recording\n"
+" -p, --playback Create a connection for playback\n"
+"\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"
+" (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"
+" being connected to.\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"
+" --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"
+msgstr ""
+"%s [options]\n"
+"\n"
+" -h, --help Affiche cette aide\n"
+" --version Affiche la version\n"
+"\n"
+" -r, --record Crée une connexion pour "
+"l'enregistrement\n"
+" -p, --playback Crée une connexion pour la lecture\n"
+"\n"
+" -v, --verbose Active le mode verbeux\n"
+"\n"
+" -s, --server=SERVEUR Le nom du serveur auquel se "
+"connecter\n"
+" -d, --device=PÉRIPHÉRIQUE Le nom de la destination/source à "
+"laquelle de connecter\n"
+" -n, --client-name=NOM Définit le nom de ce client sur le "
+"serveur\n"
+" --stream-name=NOM Définit le nom de ce flux sur le "
+"serveur\n"
+" --volume=VOLUME Indique le volume initial (linéaire) "
+"entre 0 et 65536\n"
+" --rate=TAUXDÉCHANTILLONNAGE Le taux d'échantillonnage en Hz (par "
+"défaut 44100)\n"
+" --format=FORMATDELÉCHANTILLON Le type de l'échantillon, parmi : "
+"s16le, s16be, u8, float32le,\n"
+" float32be, ulaw, alaw (par défaut "
+"s16ne)\n"
+" --channels=CANAUX Le nombre de canaux, 1 pour mono, 2 "
+"pour stéréo\n"
+" (par défaut 2)\n"
+" --channel-map=PLANDESCANAUX Plan des canaux à utiliser au lieu "
+"de celui par défaut\n"
+" --fix-format Prend le format de l'échantillon de "
+"la destination où le flux\n"
+" est en train de se connecter.\n"
+" --fix-rate Prend le taux d'échantillonnage de "
+"la destination où le flux\n"
+" est en train de se connecter.\n"
+" --fix-channels Prend le nombre et le plan des "
+"canaux de la destination \n"
+" où le flux est en train de se "
+"connecter.\n"
+" --no-remix Ne pas augmenter ou diminuer le "
+"nombre de canaux par mixage.\n"
+" --no-remap Créer le plan des canaux par index "
+"et non par nom.\n"
+" --latency=OCTETS Demande la latence indiquée en "
+"octets.\n"
+" --process-time=OCTETS Demande le temps de traitement "
+"indiqué par requête en octets.\n"
+
+#: ../src/utils/pacat.c:591
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pacat %s\n"
+"Compilé avec libpulse %s\n"
+"Lié avec libpulse %s\n"
+
+#: ../src/utils/pacat.c:647
+#, c-format
+msgid "Invalid channel map '%s'\n"
+msgstr "Plan des canaux invalide « %s »\n"
+
+#: ../src/utils/pacat.c:676
+#, c-format
+msgid "Invalid latency specification '%s'\n"
+msgstr "Spécification de latence invalide « %s »\n"
+
+#: ../src/utils/pacat.c:683
+#, c-format
+msgid "Invalid process time specification '%s'\n"
+msgstr "Spécification de temps de traitement invalide « %s »\n"
+
+#: ../src/utils/pacat.c:694
+#, c-format
+msgid "Invalid sample specification\n"
+msgstr "Spécification d'échantillon invalide\n"
+
+#: ../src/utils/pacat.c:699
+#, c-format
+msgid "Channel map doesn't match sample specification\n"
+msgstr ""
+"Le plan des canaux ne correspond pas à la spécification d'échantillon\n"
+
+#: ../src/utils/pacat.c:706
+#, c-format
+msgid "Opening a %s stream with sample specification '%s'.\n"
+msgstr "Ouverture d'un flux %s avec une spécification d'échantillon « %s ».\n"
+
+#: ../src/utils/pacat.c:706
+msgid "recording"
+msgstr "enregistrement"
+
+#: ../src/utils/pacat.c:706
+msgid "playback"
+msgstr "lecture"
+
+#: ../src/utils/pacat.c:714
+#, c-format
+msgid "open(): %s\n"
+msgstr "open() : %s\n"
+
+#: ../src/utils/pacat.c:719
+#, c-format
+msgid "dup2(): %s\n"
+msgstr "dup2() : %s\n"
+
+#: ../src/utils/pacat.c:729
+#, c-format
+msgid "Too many arguments.\n"
+msgstr "Trop de paramètres.\n"
+
+#: ../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 "Échec de pa_mainloop_new().\n"
+
+#: ../src/utils/pacat.c:763
+#, c-format
+msgid "io_new() failed.\n"
+msgstr "Échec de io_new().\n"
+
+#: ../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 "Échec de pa_context_new().\n"
+
+#: ../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: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 "Échec de pa_mainloop_run().\n"
+
+#: ../src/utils/pasuspender.c:81
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork() : %s\n"
+
+#: ../src/utils/pasuspender.c:92
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp() : %s\n"
+
+#: ../src/utils/pasuspender.c:109
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr "Échec lors de la suspension : %s\n"
+
+#: ../src/utils/pasuspender.c:124
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr "Échec lors de la reprise : %s\n"
+
+#: ../src/utils/pasuspender.c:147
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr ""
+"AVERTISSEMENT : le serveur de son n'est pas local, suspension annulée.\n"
+
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
+#: ../src/utils/paplay.c:191
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr "SIGINT reçu, fermeture.\n"
+
+#: ../src/utils/pasuspender.c:194
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr "AVERTISSEMENT : le processus fils a été terminé par le signal %u\n"
+
+#: ../src/utils/pasuspender.c:212
+#, c-format
+msgid ""
+"%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"
+"\n"
+msgstr ""
+"%s [options] ... \n"
+"\n"
+" -h, --help Affiche cette aide\n"
+" --version Affiche la version\n"
+" -s, --server=SERVEUR Le nom du serveur auquel se "
+"connecter\n"
+"\n"
+
+#: ../src/utils/pasuspender.c:251
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pasuspender %s\n"
+"Compilé avec libpulse %s\n"
+"Lié avec libpulse %s\n"
+
+#: ../src/utils/pactl.c:107
+#, c-format
+msgid "Failed to get statistics: %s\n"
+msgstr "Échec lors de l'obtention des statistiques : %s\n"
+
+#: ../src/utils/pactl.c:113
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr "En cours d'utilisation : %u blocs contenant au total %s octets.\n"
+
+#: ../src/utils/pactl.c:116
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
+"Alloué pendant l'ensemble de la durée d'exécution : %u blocs contenant au "
+"total %s octets.\n"
+
+#: ../src/utils/pactl.c:119
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr "Taille du cache de l'échantillon : %s\n"
+
+#: ../src/utils/pactl.c:128
+#, c-format
+msgid "Failed to get server information: %s\n"
+msgstr "Échec lors de l'obtention des informations du serveur : %s\n"
+
+#: ../src/utils/pactl.c:135
+#, c-format
+msgid ""
+"User name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %08x\n"
+msgstr ""
+"Nom d'utilisateur : %s\n"
+"Nom d'hôte : %s\n"
+"Nom du serveur : %s\n"
+"Version du serveur : %s\n"
+"Spécification d'échantillon par défaut : %s\n"
+"Destination par défaut : %s\n"
+"Source par défaut : %s\n"
+"Cookie : %08x\n"
+
+#: ../src/utils/pactl.c:160
+#, c-format
+msgid "Failed to get sink information: %s\n"
+msgstr "Échec lors de l'obtention des informations sur la destination : %s\n"
+
+# demander à Lennart s'il s'agit de monitor of source
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"*** Sink #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor Source: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Destination #%u ***\n"
+"Nom : %s\n"
+"Pilote : %s\n"
+"Spécification de l'échantillon : %s\n"
+"Plan des canaux : %s\n"
+"Module propriétaire : %u\n"
+"Volume : %s\n"
+"Moniteur de la source : %s\n"
+"Latence : %0.0f µs, %0.0f µs configurée \n"
+"Drapeaux : %s%s%s%s%s%s\n"
+"Propriétés :\n"
+"%s"
+
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
+msgid "muted"
+msgstr "en sourdine"
+
+#: ../src/utils/pactl.c:212
+#, c-format
+msgid "Failed to get source information: %s\n"
+msgstr "Échec lors de l'obtention des informations sur la source : %s\n"
+
+#: ../src/utils/pactl.c:228
+#, c-format
+msgid ""
+"*** Source #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor of Sink: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Source #%u ***\n"
+"Nom : %s\n"
+"Pilote : %s\n"
+"Spécification de l'échantillon : %s\n"
+"Plan des canaux : %s\n"
+"Module propriétaire : %u\n"
+"Volume : %s\n"
+"Moniteur de la destination : %s\n"
+"Latence : %0.0f µs, %0.0f µs configurée \n"
+"Drapeaux : %s%s%s%s%s%s\n"
+"Propriétés :\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
+msgid "n/a"
+msgstr "n/d"
+
+#: ../src/utils/pactl.c:263
+#, c-format
+msgid "Failed to get module information: %s\n"
+msgstr "Échec lors de l'obtention des informations du module : %s\n"
+
+#: ../src/utils/pactl.c:281
+#, c-format
+msgid ""
+"*** Module #%u ***\n"
+"Name: %s\n"
+"Argument: %s\n"
+"Usage counter: %s\n"
+"Auto unload: %s\n"
+msgstr ""
+"*** Module #%u ***\n"
+"Nom : %s\n"
+"Paramètre : %s\n"
+"Nombre d'utilisations : %s\n"
+"Déchargement automatique : %s\n"
+
+#: ../src/utils/pactl.c:298
+#, c-format
+msgid "Failed to get client information: %s\n"
+msgstr "Échec lors de l'obtention des informations du client : %s\n"
+
+#: ../src/utils/pactl.c:316
+#, c-format
+msgid ""
+"*** Client #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Client #%u ***\n"
+"Pilote : %s\n"
+"Module propriétaire : %s\n"
+"Propriétés :\n"
+"%s"
+
+#: ../src/utils/pactl.c:333
+#, c-format
+msgid "Failed to get sink input information: %s\n"
+msgstr ""
+"Échec lors de l'obtention des informations de l'entrée de la destination : %"
+"s\n"
+
+#: ../src/utils/pactl.c:352
+#, c-format
+msgid ""
+"*** Sink Input #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Sink: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Volume: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Sink Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Entrée de la destination #%u ***\n"
+"Pilote : %s\n"
+"Module propriétaire : %s\n"
+"Client : %s\n"
+"Destination : %u\n"
+"Spécification de l'échantillon : %s\n"
+"Plan des canaux : %s\n"
+"Volume : %s\n"
+"Latence du tampon : %0.0f µs\n"
+"Latence de la destination : %0.0f µs\n"
+"Méthode de rééchantillonnage : %s\n"
+"Propriétés :\n"
+"%s"
+
+#: ../src/utils/pactl.c:385
+#, c-format
+msgid "Failed to get source output information: %s\n"
+msgstr ""
+"Échec lors de l'obtention des informations de la sortie de la source : %s\n"
+
+#: ../src/utils/pactl.c:405
+#, c-format
+msgid ""
+"*** Source Output #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Source: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Source Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Source Output #%u ***\n"
+"Pilote : %s\n"
+"Module propriétaire : %s\n"
+"Client : %s\n"
+"Source : %u\n"
+"Spécification de l'échantillon : %s\n"
+"Plan des canaux : %s\n"
+"Latence du tampon : %0.0f µs\n"
+"Latence de la source : %0.0f µs\n"
+"Méthode de rééchantillonnage : %s\n"
+"Propriétés :\n"
+"%s"
+
+#: ../src/utils/pactl.c:436
+#, c-format
+msgid "Failed to get sample information: %s\n"
+msgstr "Échec lors de l'obtention des informations de l'échantillon : %s\n"
+
+# Lazy ?
+# load-sample-lazy = Create a new entry in the sample cache, but don't load
+# the sample immediately. The sample is loaded only when it is first used
+#: ../src/utils/pactl.c:455
+#, c-format
+msgid ""
+"*** Sample #%u ***\n"
+"Name: %s\n"
+"Volume: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Duration: %0.1fs\n"
+"Size: %s\n"
+"Lazy: %s\n"
+"Filename: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Échantillon #%u ***\n"
+"Nom : %s\n"
+"Volume : %s\n"
+"Spécification de l'échantillon : %s\n"
+"Plan des canaux : %s\n"
+"Durée : %0.1f s\n"
+"Taille : %s\n"
+"Cache retardé : %s\n"
+"Nom de fichier : %s\n"
+"Propriétés :\n"
+"%s"
+
+#: ../src/utils/pactl.c:481
+#, c-format
+msgid "Failed to get autoload information: %s\n"
+msgstr ""
+"Échec lors de l'obtention des informations du chargement automatique : %s\n"
+
+#: ../src/utils/pactl.c:497
+#, c-format
+msgid ""
+"*** Autoload Entry #%u ***\n"
+"Name: %s\n"
+"Type: %s\n"
+"Module: %s\n"
+"Argument: %s\n"
+msgstr ""
+"*** Entrée de chargement automatique #%u ***\n"
+"Nom : %s\n"
+"Type : %s\n"
+"Module : %s\n"
+"Paramètre : %s\n"
+
+#: ../src/utils/pactl.c:504
+msgid "sink"
+msgstr "destination"
+
+#: ../src/utils/pactl.c:504
+msgid "source"
+msgstr "source"
+
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
+#, c-format
+msgid "Failure: %s\n"
+msgstr "Échec : %s\n"
+
+#: ../src/utils/pactl.c:545
+#, c-format
+msgid "Failed to upload sample: %s\n"
+msgstr "Échec lors de l'envoi de l'échantillon : %s\n"
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid "Premature end of file\n"
+msgstr "Fin prématurée du fichier\n"
+
+#: ../src/utils/pactl.c:678
+#, c-format
+msgid ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -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"
+msgstr ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample NOMDEFICHIER [NOM]\n"
+"%s [options] play-sample NOM [DEST]\n"
+"%s [options] remove-sample NOM\n"
+"%s [options] move-sink-input ID DEST\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NOM [PARAMS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [DEST] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -h, --help Affiche cette aide\n"
+" --version Affiche la version\n"
+"\n"
+" -s, --server=SERVEUR Le nom du serveur auquel se "
+"connecter\n"
+" -n, --client-name=NOM Définit le nom de ce client sur le "
+"serveur\n"
+
+#: ../src/utils/pactl.c:729
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pactl %s\n"
+"Compilé avec libpulse %s\n"
+"Lié avec libpulse %s\n"
+
+#: ../src/utils/pactl.c:768
+#, c-format
+msgid "Please specify a sample file to load\n"
+msgstr "Veuillez indiquer un fichier d'échantillon à charger\n"
+
+#: ../src/utils/pactl.c:790
+#, c-format
+msgid "Failed to open sound file.\n"
+msgstr "Échec lors de l'ouverture du fichier audio.\n"
+
+#: ../src/utils/pactl.c:802
+#, c-format
+msgid "You have to specify a sample name to play\n"
+msgstr "Vous devez indiquer un nom d'échantillon à lire\n"
+
+#: ../src/utils/pactl.c:814
+#, c-format
+msgid "You have to specify a sample name to remove\n"
+msgstr "Vous devez indiquer un nom d'échantillon à supprimer\n"
+
+#: ../src/utils/pactl.c:822
+#, c-format
+msgid "You have to specify a sink input index and a sink\n"
+msgstr ""
+"Vous devez indiquer un index de sortie de destination et une destination\n"
+
+#: ../src/utils/pactl.c:831
+#, c-format
+msgid "You have to specify a source output index and a source\n"
+msgstr "Vous devez indiquer un index de sortie de source et une source\n"
+
+#: ../src/utils/pactl.c:845
+#, c-format
+msgid "You have to specify a module name and arguments.\n"
+msgstr "Vous devez indiquer un nom de module et des paramètres.\n"
+
+#: ../src/utils/pactl.c:865
+#, c-format
+msgid "You have to specify a module index\n"
+msgstr "Vous devez indiquer un index de module\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 ""
+"Vous ne pouvez pas indiquer plus d'une destination. Vous devez indiquer au "
+"moins une valeur booléenne.\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 ""
+"Vous ne pouvez pas indiquer plus d'une source. Vous devez indiquer au moins "
+"une valeur booléenne.\n"
+
+#: ../src/utils/pactl.c:904
+#, c-format
+msgid "No valid command specified.\n"
+msgstr "Aucune commande valide indiquée.\n"
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%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"
+" -r Remove PulseAudio data from X11 display\n"
+msgstr ""
+"%s [-D visuel] [-S serveur] [-O destination] [-I source] [-c fichier] [-d|-"
+"e|-i|-r]\n"
+"\n"
+" -d Affiche les données PulseAudio actuelles attachées au visuel X11 (par "
+"défaut)\n"
+" -e Exporte les données PulseAudio locales vers le visuel X11\n"
+" -i Importe les données PulseAudio depuis le visuel X11 vers les "
+"variables de l'environnement local et le fichier de cookie.\n"
+" -r Enlève les données PulseAudio du visuel X11\n"
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "Échec lors de l'analyse de la ligne de commande.\n"
+
+#: ../src/utils/pax11publish.c:108
+#, c-format
+msgid "Server: %s\n"
+msgstr "Serveur : %s\n"
+
+#: ../src/utils/pax11publish.c:110
+#, c-format
+msgid "Source: %s\n"
+msgstr "Source : %s\n"
+
+#: ../src/utils/pax11publish.c:112
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Destination : %s\n"
+
+#: ../src/utils/pax11publish.c:114
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Cookie : %s\n"
+
+#: ../src/utils/pax11publish.c:132
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr "Échec lors de l'analyse des données du cookie\n"
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr "Échec lors de l'enregistrement des données du cookie\n"
+
+#: ../src/utils/pax11publish.c:152
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr "Échec lors du chargement du fichier de configuration du client.\n"
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr ""
+"Échec lors de la lecture des données de configuration de l'environnement.\n"
+
+# Fully Qualified Domain Name
+#: ../src/utils/pax11publish.c:174
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr "Échec lors de l'obtention du FQDN (« nom de domaine complet »).\n"
+
+#: ../src/utils/pax11publish.c:194
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr "Échec lors du chargement des données du cookie\n"
+
+#: ../src/utils/pax11publish.c:211
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "Pas encore implémenté.\n"
+
+#: ../src/utils/pacmd.c:64
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr "socket(PF_UNIX, SOCK_STREAM, 0) : %s"
+
+#: ../src/utils/pacmd.c:81
+#, c-format
+msgid "connect(): %s"
+msgstr "connect() : %s"
+
+#: ../src/utils/pacmd.c:89
+msgid "Failed to kill PulseAudio daemon."
+msgstr "Impossible de tuer le démon PulseAudio."
+
+#: ../src/utils/pacmd.c:97
+msgid "Daemon not responding."
+msgstr "Le démon ne répond pas."
+
+#: ../src/utils/pacmd.c:112
+#, c-format
+msgid "select(): %s"
+msgstr "select() : %s"
+
+#: ../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
+#, c-format
+msgid "write(): %s"
+msgstr "write() : %s"
+
+#: ../src/utils/paplay.c:139
+#, c-format
+msgid "Stream successfully created\n"
+msgstr "Création du flux réussie\n"
+
+#: ../src/utils/paplay.c:144
+#, c-format
+msgid "Stream errror: %s\n"
+msgstr "Erreur du flux : %s\n"
+
+#: ../src/utils/paplay.c:165
+#, c-format
+msgid "Connection established.\n"
+msgstr "Connexion établie.\n"
+
+#: ../src/utils/paplay.c:198
+#, c-format
+msgid ""
+"%s [options] [FILE]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -v, --verbose Enable verbose operation\n"
+"\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"
+" --channel-map=CHANNELMAP Set the channel map to the use\n"
+msgstr ""
+"%s [options] [FICHIER]\n"
+"\n"
+" -h, --help Affiche cette aide\n"
+" --version Affiche la version\n"
+"\n"
+" -v, --verbose Active le mode verbeux\n"
+"\n"
+" -s, --server=SERVEUR Le nom du serveur auquel se "
+"connecter\n"
+" -d, --device=PÉRIPHÉRIQUE Le nom de la destination à laquelle "
+"se connecter\n"
+" -n, --client-name=NOM Définit le nom de ce client sur le "
+"serveur\n"
+" --stream-name=NOM Définit le nom de ce flux sur le "
+"serveur\n"
+" --volume=VOLUME Définit le volume initial (linéaire) "
+"entre 0 et 65536\n"
+" --channel-map=PLANDESCANAUX Définit le plan des canaux à "
+"utiliser\n"
+
+#: ../src/utils/paplay.c:255
+#, c-format
+msgid ""
+"paplay %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"paplay %s\n"
+"Compilé avec libpulse %s\n"
+"Lié avec libpulse %s\n"
+
+#: ../src/utils/paplay.c:292
+#, c-format
+msgid "Invalid channel map\n"
+msgstr "Plan des canaux invalide\n"
+
+#: ../src/utils/paplay.c:314
+#, c-format
+msgid "Failed to open file '%s'\n"
+msgstr "Échec lors de l'ouverture du fichier « %s »\n"
+
+#: ../src/utils/paplay.c:350
+#, c-format
+msgid "Channel map doesn't match file.\n"
+msgstr "Le plan des canaux ne correspond pas au fichier.\n"
+
+#: ../src/utils/paplay.c:376
+#, 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
new file mode 100644
index 00000000..5c5b3b4f
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,2113 @@
+# translation of pl.po to Polish
+# Piotr Drąg <piotrdrag@gmail.com>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pl\n"
+"Report-Msgid-Bugs-To: \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"
+"MIME-Version: 1.0\n"
+"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
+msgid "Failed to add bind-now-loader."
+msgstr "Dodanie bind-now-loader nie powiodło się."
+
+#: ../src/daemon/ltdl-bind-now.c:184
+msgid "Failed to find original dlopen loader."
+msgstr ""
+"Znalezienie oryginalnego programu wczytującego dlopen nie powiodło się."
+
+#: ../src/daemon/polkit.c:55
+#, c-format
+msgid "Cannot connect to system bus: %s"
+msgstr "Nie można połączyć się z magistralą systemową: %s"
+
+#: ../src/daemon/polkit.c:65
+#, c-format
+msgid "Cannot get caller from PID: %s"
+msgstr "Nie można uzyskać obiektu caller z PID: %s"
+
+#: ../src/daemon/polkit.c:77
+msgid "Cannot set UID on caller object."
+msgstr "Nie można ustawić UID obiektu caller."
+
+#: ../src/daemon/polkit.c:82
+msgid "Failed to get CK session."
+msgstr "Uzyskanie sesji CK nie powiodło się."
+
+#: ../src/daemon/polkit.c:90
+msgid "Cannot set UID on session object."
+msgstr "Nie można ustawić UID obiektowi sesji."
+
+#: ../src/daemon/polkit.c:95
+msgid "Cannot allocate PolKitAction."
+msgstr "Nie można przydzielić PolKitAction."
+
+#: ../src/daemon/polkit.c:100
+msgid "Cannot set action_id"
+msgstr "Nie można ustawić action_id"
+
+#: ../src/daemon/polkit.c:105
+msgid "Cannot allocate PolKitContext."
+msgstr "Nie można przydzielić PolKitContext."
+
+#: ../src/daemon/polkit.c:110
+#, c-format
+msgid "Cannot initialize PolKitContext: %s"
+msgstr "Nie można zainicjować PolKitContext: %s"
+
+#: ../src/daemon/polkit.c:119
+#, c-format
+msgid "Could not determine whether caller is authorized: %s"
+msgstr "Nie można ustalić, czy obiekt caller jest upoważniony: %s"
+
+#: ../src/daemon/polkit.c:139
+#, c-format
+msgid "Cannot obtain auth: %s"
+msgstr "Nie można uzyskać upoważnienia: %s"
+
+#: ../src/daemon/polkit.c:148
+#, c-format
+msgid "PolicyKit responded with '%s'"
+msgstr "PolicyKit zwróciło \"%s\""
+
+#: ../src/daemon/main.c:134
+#, c-format
+msgid "Got signal %s."
+msgstr "Otrzymano sygnał %s."
+
+#: ../src/daemon/main.c:161
+msgid "Exiting."
+msgstr "Wyłączanie."
+
+#: ../src/daemon/main.c:179
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Znalezienie użytkownika \"%s\" nie powiodło się."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Znalezienie grupy \"%s\" nie powiodło się."
+
+#: ../src/daemon/main.c:188
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr "Znaleziono użytkownika \"%s\" (UID %lu) i grupę \"%s\" (GID %lu)."
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr "GID użytkownika \"%s\" i grupy \"%s\" nie zgadzają się."
+
+#: ../src/daemon/main.c:198
+#, c-format
+msgid "Home directory of user '%s' is not '%s', ignoring."
+msgstr "Folder domowy użytkownika \"%s\" nie jest \"%s\", ignorowanie."
+
+#: ../src/daemon/main.c:201 ../src/daemon/main.c:206
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "Utworzenie \"%s\" nie powiodło się: %s"
+
+#: ../src/daemon/main.c:213
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr "Zmiana listy grup nie powiodła się: %s"
+
+#: ../src/daemon/main.c:229
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr "Zmiana GID nie powiodła się: %s"
+
+#: ../src/daemon/main.c:245
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr "Zmiana UID nie powiodła się: %s"
+
+#: ../src/daemon/main.c:259
+msgid "Successfully dropped root privileges."
+msgstr "Pomyślnie porzucono uprawnienia roota."
+
+#: ../src/daemon/main.c:267
+msgid "System wide mode unsupported on this platform."
+msgstr "Tryb systemowy nie jest obsługiwany na tej platformie."
+
+#: ../src/daemon/main.c:285
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) nie powiodło się: %s"
+
+#: ../src/daemon/main.c:425
+msgid "Failed to parse command line."
+msgstr "Analiza wiersza poleceń nie powiodła się."
+
+#: ../src/daemon/main.c:441
+#, c-format
+msgid "We're in the group '%s', allowing high-priority scheduling."
+msgstr ""
+"Jesteśmy w grupie \"%s\", co umożliwia szeregowanie o wysokim priorytecie."
+
+#: ../src/daemon/main.c:448
+#, c-format
+msgid "We're in the group '%s', allowing real-time scheduling."
+msgstr ""
+"Jesteśmy w grupie \"%s\", co umożliwia szeregowanie w czasie rzeczywistym."
+
+#: ../src/daemon/main.c:456
+msgid "PolicyKit grants us acquire-high-priority privilege."
+msgstr "PolicyKit nadał uprawnienie \"acquire-high-priority\"."
+
+#: ../src/daemon/main.c:459
+msgid "PolicyKit refuses acquire-high-priority privilege."
+msgstr "PolicyKit odmówił nadania uprawnienia \"acquire-high-priority\"."
+
+#: ../src/daemon/main.c:464
+msgid "PolicyKit grants us acquire-real-time privilege."
+msgstr "PolicyKit nadał uprawnienie \"acquire-real-time\"."
+
+#: ../src/daemon/main.c:467
+msgid "PolicyKit refuses acquire-real-time privilege."
+msgstr "PolicyKit odmówił nadania uprawnienia \"acquire-real-time\"."
+
+#: ../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"
+"We are not in group '"
+msgstr ""
+"Wywołane SUID roota i szeregowanie w czasie rzeczywistym/o wysokim "
+"priorytecie zostało zażądane w konfiguracji. Mimo to brak niezbędnych "
+"uprawnień:\n"
+"Nie jesteśmy w grupie \""
+
+#: ../src/daemon/main.c:497
+msgid ""
+"High-priority scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+"Szeregowanie o wysokim priorytecie jest włączone w konfiguracji, ale nie "
+"jest zezwolone przez politykę."
+
+#: ../src/daemon/main.c:522
+msgid "Successfully increased RLIMIT_RTPRIO"
+msgstr "Pomyślnie zwiększono RLIMIT_RTPRIO"
+
+#: ../src/daemon/main.c:525
+#, c-format
+msgid "RLIMIT_RTPRIO failed: %s"
+msgstr "RLIMIT_RTPRIO nie powiodło się: %s"
+
+#: ../src/daemon/main.c:532
+msgid "Giving up CAP_NICE"
+msgstr "Oddawanie CAP_NICE"
+
+#: ../src/daemon/main.c:539
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+"Szeregowanie w czasie rzeczywistym jest włączone w konfiguracji, ale nie "
+"jest zezwolone przez politykę."
+
+#: ../src/daemon/main.c:597
+msgid "Daemon not running"
+msgstr "Demon nie jest uruchomiony"
+
+#: ../src/daemon/main.c:599
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr "Demon jest uruchomiony jako PID %u"
+
+#: ../src/daemon/main.c:609
+#, c-format
+msgid "Failed to kill daemon: %s"
+msgstr "Zniszczenie demona nie powiodło się: %s"
+
+#: ../src/daemon/main.c:627
+msgid ""
+"This program is not intended to be run as root (unless --system is "
+"specified)."
+msgstr ""
+"Ten program nie powinien być uruchomiany jako root (chyba, że podano --"
+"system)"
+
+#: ../src/daemon/main.c:629
+msgid "Root priviliges required."
+msgstr "Wymagane są uprawnienia roota."
+
+#: ../src/daemon/main.c:634
+msgid "--start not supported for system instances."
+msgstr "--start nie jest obsługiwane przy uruchamianiu systemowym."
+
+#: ../src/daemon/main.c:639
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr ""
+"Uruchamianie w trybie systemowym, ale --disallow-exit nie jest ustawione!"
+
+#: ../src/daemon/main.c:642
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr ""
+"Uruchamianie w trybie systemowym, ale --disallow-module-loading nie jest "
+"ustawione!"
+
+#: ../src/daemon/main.c:645
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr "Uruchamianie w trybie systemowym, wymuszanie wyłączenia trybu SHM!"
+
+#: ../src/daemon/main.c:650
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+"Uruchamianie w trybie systemowym, wymuszanie wyłączenia czasu oczekiwania na "
+"zakończenie!"
+
+#: ../src/daemon/main.c:677
+msgid "Failed to acquire stdio."
+msgstr "Uzyskanie standardowego wejścia/wyjścia nie powiodło się"
+
+#: ../src/daemon/main.c:683
+#, c-format
+msgid "pipe failed: %s"
+msgstr "potok nie powiódł się: %s"
+
+#: ../src/daemon/main.c:688
+#, c-format
+msgid "fork() failed: %s"
+msgstr "fork() nie powiodło się: %s"
+
+#: ../src/daemon/main.c:702
+#, c-format
+msgid "read() failed: %s"
+msgstr "read() nie powiodło się: %s"
+
+#: ../src/daemon/main.c:708
+msgid "Daemon startup failed."
+msgstr "Uruchomienie demona nie powiodło się."
+
+#: ../src/daemon/main.c:710
+msgid "Daemon startup successful."
+msgstr "Pomyślnie uruchomiono demona."
+
+#: ../src/daemon/main.c:780
+#, c-format
+msgid "This is PulseAudio %s"
+msgstr "To jest PulseAudio %s"
+
+#: ../src/daemon/main.c:781
+#, c-format
+msgid "Compilation host: %s"
+msgstr "Komputer kompilacji: %s"
+
+#: ../src/daemon/main.c:782
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr "CFLAGS kompilacji: %s"
+
+#: ../src/daemon/main.c:785
+#, c-format
+msgid "Running on host: %s"
+msgstr "Uruchamianie na komputerze: %s"
+
+#: ../src/daemon/main.c:788
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr "Rozmiar strony to %lu bajtów"
+
+#: ../src/daemon/main.c:791
+msgid "Compiled with Valgrind support: yes"
+msgstr "Skompilowano z obsługą Valgrind: tak"
+
+#: ../src/daemon/main.c:793
+msgid "Compiled with Valgrind support: no"
+msgstr "Skompilowano z obsługą Valgrind: nie"
+
+#: ../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:801
+msgid "Optimized build: no"
+msgstr "Budowanie optymalizowane: nie"
+
+#: ../src/daemon/main.c:805
+msgid "Failed to get machine ID"
+msgstr "Uzyskanie identyfikatora komputera nie powiodło się"
+
+#: ../src/daemon/main.c:808
+#, c-format
+msgid "Machine ID is %s."
+msgstr "Identyfikator komputera to %s."
+
+#: ../src/daemon/main.c:813
+#, c-format
+msgid "Using runtime directory %s."
+msgstr "Używanie folderu wykonywania %s."
+
+#: ../src/daemon/main.c:818
+#, c-format
+msgid "Using state directory %s."
+msgstr "Używanie folderu stanu %s."
+
+#: ../src/daemon/main.c:821
+#, c-format
+msgid "Running in system mode: %s"
+msgstr "Uruchamianie w trybie systemowym: %s"
+
+#: ../src/daemon/main.c:836
+msgid "pa_pid_file_create() failed."
+msgstr "pa_pid_file_create() nie powiodło się."
+
+#: ../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:850
+msgid ""
+"Dude, your kernel stinks! The chef's recommendation today is Linux with high-"
+"resolution timers enabled!"
+msgstr ""
+"Koleś, twoje jądro śmierdzi! Szef kuchni poleca dzisiaj Linuksa w włączonymi "
+"zegarami o wysokiej rozdzielczości!"
+
+#: ../src/daemon/main.c:860
+msgid "pa_core_new() failed."
+msgstr "pa_core_new() nie powiodło się."
+
+#: ../src/daemon/main.c:921
+msgid "Failed to initialize daemon."
+msgstr "Zainicjowanie demona nie powiodło się."
+
+#: ../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: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:944
+msgid "Daemon startup complete."
+msgstr "Zakończono uruchamianie demona."
+
+#: ../src/daemon/main.c:950
+msgid "Daemon shutdown initiated."
+msgstr "Zainicjowano wyłączenie demona."
+
+#: ../src/daemon/main.c:971
+msgid "Daemon terminated."
+msgstr "Demon został zniszczony."
+
+#: ../src/daemon/cmdline.c:117
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"COMMANDS:\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+" --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"
+" -k --kill Kill a running daemon\n"
+" --check Check for a running daemon\n"
+"\n"
+"OPTIONS:\n"
+" --system[=BOOL] Run as system-wide instance\n"
+" -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"
+" with elevated RLIMIT_NICE)\n"
+" --realtime[=BOOL] Try to enable realtime scheduling\n"
+" (only available as root, when SUID "
+"or\n"
+" with elevated RLIMIT_RTPRIO)\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"
+" time passed\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"
+" 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"
+" objects (plugins)\n"
+" --resample-method=METHOD Use the specified resampling method\n"
+" (See --dump-resample-methods for\n"
+" possible values)\n"
+" --use-pid-file[=BOOL] Create a PID file\n"
+" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
+" platforms that support it.\n"
+" --disable-shm[=BOOL] Disable shared memory support.\n"
+"\n"
+"STARTUP SCRIPT:\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"
+" after startup\n"
+"\n"
+" -n Don't load default script file\n"
+msgstr ""
+"%s [opcje]\n"
+"\n"
+"POLECENIA:\n"
+" -h, --help Wyświetla tę pomoc\n"
+" --version Wyświetla wersję\n"
+" --dump-conf Zrzuca domyślną konfigurację\n"
+" --dump-modules Zrzuca listę dostępnych modułów\n"
+" --dump-resample-methods Zrzuca dostępne metody resamplingu\n"
+" --cleanup-shm Czyści stare fragmenty pamięci "
+"współdzielonej\n"
+" --start Uruchamia demona, jeśli nie jest "
+"uruchomiony\n"
+" -k --kill Niszczy uruchomionego demona\n"
+" --check Sprawdza, czy demon jest "
+"uruchomiony\n"
+"\n"
+"OPCJE:\n"
+" --system[=ZMIENNALOGICZNA] Uruchamia w trybie systemowym\n"
+" -D, --daemonize[=ZMIENNALOGICZNA] Tworzy demona po uruchomieniu\n"
+" --fail[=ZMIENNALOGICZNA] Wyłącza, kiedy uruchomienie nie "
+"powiedzie się\n"
+" --high-priority[=ZMIENNALOGICZNA] Próbuje ustawić wysoki poziom nice\n"
+" (dostępne tylko jako root, na SUID "
+"lub\n"
+" z podniesionym RLIMIT_NICE)\n"
+" --realtime[=ZMIENNALOGICZNA] Próbuje ustawić szeregowanie w "
+"czasie rzeczywistym\n"
+" (dostępne tylko jako root, na SUID "
+"lub\n"
+" 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"
+" --disallow-exit[=ZMIENNALOGICZNA] Nie zezwala użytkownikowi na żądanie "
+"wyłączenia\n"
+" --exit-idle-time=SEKUNDY Niszczy demona, kiedy jest zajęty i "
+"upłynął\n"
+" ten czas\n"
+" --module-idle-time=SEKUNDY Usuwa automatycznie wczytane moduły, "
+"kiedy jest\n"
+" zajęty i upłynął ten czas\n"
+" --scache-idle-time=SEKUNDY Usuwa automatycznie wczytane próbki, "
+"kiedy jest\n"
+" zajęty i upłynął ten czas\n"
+" --log-level[=POZIOM] Zwiększa lub ustaw poziom "
+"wyświetlanych informacji\n"
+" -v Zwiększa poziom wyświetlanych "
+"informacji\n"
+" --log-target={auto,syslog,stderr} Określa dziennik docelowy\n"
+" -p, --dl-search-path=ŚCIEŻKA Ustawia ścieżkę wyszukiwania dla "
+"dynamicznie\n"
+" współdzielonych obiektów (wtyczek)\n"
+" --resample-method=METODA Używa podanej metody resamplingu\n"
+" (zobacz --dump-resample-methods,\n"
+" aby poznać możliwe wartości)\n"
+" --use-pid-file[=ZMIENNALOGICZNA] Tworzy plik PID\n"
+" --no-cpu-limit[=ZMIENNALOGICZNA] Nie instaluje ograniczenia zasobów\n"
+" procesora na obsługujących je "
+"platformach.\n"
+" --disable-shm[=ZMIENNALOGICZNA] Wyłącza obsługę pamięci "
+"współdzielonej.\n"
+"\n"
+"SKRYPT STARTOWY:\n"
+" -L, --load=\"PARAMETRY MODUŁU\" Wczytuje podany moduł wtyczki z\n"
+" podanym parametrem\n"
+" -F, --file=NAZWAPLIKU Wykonuje podany skrypt\n"
+" -C Otwiera wiersz poleceń na "
+"uruchomionym TTY\n"
+" po uruchomieniu\n"
+"\n"
+" -n Nie wczytuje domyślnego pliku "
+"skryptu\n"
+
+#: ../src/daemon/cmdline.c:245
+msgid "--daemonize expects boolean argument"
+msgstr "--daemonize oczekuje parametru w postaci zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:252
+msgid "--fail expects boolean argument"
+msgstr "--fail oczekuje parametru w postaci zmiennej logicznej"
+
+#: ../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 oczekuje parametru poziomu dziennika (numeryczny w zakresie 0..4 "
+"lub jeden z debug, info, notice, warn, error)."
+
+#: ../src/daemon/cmdline.c:274
+msgid "--high-priority expects boolean argument"
+msgstr "--high-priority oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:281
+msgid "--realtime expects boolean argument"
+msgstr "-realtime oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:288
+msgid "--disallow-module-loading expects boolean argument"
+msgstr "--disallow-module-loading oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:295
+msgid "--disallow-exit boolean argument"
+msgstr "--disallow-exit zmienna logiczna"
+
+#: ../src/daemon/cmdline.c:302
+msgid "--use-pid-file expects boolean argument"
+msgstr "--use-pid-file oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:319
+msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+msgstr ""
+"Nieprawidłowy dziennik docelowy: należy użyć \"syslog\", \"stderr\" lub "
+"\"auto\"."
+
+#: ../src/daemon/cmdline.c:338
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr "Nieprawidłowa metoda resamplingu \"%s\"."
+
+#: ../src/daemon/cmdline.c:345
+msgid "--system expects boolean argument"
+msgstr "--system oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:352
+msgid "--no-cpu-limit expects boolean argument"
+msgstr "--no-cpu-limit oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/cmdline.c:359
+msgid "--disable-shm expects boolean argument"
+msgstr "--disable-shm oczekuje parametru zmiennej logicznej"
+
+#: ../src/daemon/dumpmodules.c:60
+#, c-format
+msgid "Name: %s\n"
+msgstr "Nazwa: %s\n"
+
+#: ../src/daemon/dumpmodules.c:63
+#, c-format
+msgid "No module information available\n"
+msgstr "Brak informacji o module\n"
+
+#: ../src/daemon/dumpmodules.c:66
+#, c-format
+msgid "Version: %s\n"
+msgstr "Wersja: %s\n"
+
+#: ../src/daemon/dumpmodules.c:68
+#, c-format
+msgid "Description: %s\n"
+msgstr "Opis: %s\n"
+
+#: ../src/daemon/dumpmodules.c:70
+#, c-format
+msgid "Author: %s\n"
+msgstr "Autor: %s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Usage: %s\n"
+msgstr "Użycie: %s\n"
+
+#: ../src/daemon/dumpmodules.c:73
+#, c-format
+msgid "Load Once: %s\n"
+msgstr "Wczytanie jednorazowe: %s\n"
+
+#: ../src/daemon/dumpmodules.c:77
+#, c-format
+msgid "Path: %s\n"
+msgstr "Ścieżka: %s\n"
+
+#: ../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:221
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr "[%s:%u] Nieprawidłowy poziom dziennika \"%s\"."
+
+#: ../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:260
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr "[%s:%u] Nieprawidłowy rlimit \"%s\"."
+
+#: ../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:283
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr "[%s:%u] Nieprawidłowy format próbki \"%s\"."
+
+#: ../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: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: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:355
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr "[%s:%u] Nieprawidłowy rozmiar fragmentu \"%s\"."
+
+#: ../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:570
+#, c-format
+msgid "Failed to open configuration file: %s"
+msgstr "Otwarcie pliku konfiguracji nie powiodło się: %s"
+
+#: ../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:63
+msgid "Dropping root priviliges."
+msgstr "Porzucanie uprawnień roota."
+
+#: ../src/daemon/caps.c:103
+msgid "Limited capabilities successfully to CAP_SYS_NICE."
+msgstr "Pomyślnie ograniczono możliwości do CAP_SYS_NICE."
+
+#: ../src/pulse/channelmap.c:102
+msgid "Mono"
+msgstr "Mono"
+
+#: ../src/pulse/channelmap.c:104
+msgid "Front Center"
+msgstr "Przedni środkowy"
+
+#: ../src/pulse/channelmap.c:105
+msgid "Front Left"
+msgstr "Przedni lewy"
+
+#: ../src/pulse/channelmap.c:106
+msgid "Front Right"
+msgstr "Przedni prawy"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Rear Center"
+msgstr "Tylny środkowy"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Rear Left"
+msgstr "Tylny lewy"
+
+#: ../src/pulse/channelmap.c:110
+msgid "Rear Right"
+msgstr "Tylny prawy"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Low Frequency Emmiter"
+msgstr "Subwoofer"
+
+#: ../src/pulse/channelmap.c:114
+msgid "Front Left-of-center"
+msgstr "Przedni lewy po środku"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Front Right-of-center"
+msgstr "Przedni prawy po środku"
+
+#: ../src/pulse/channelmap.c:117
+msgid "Side Left"
+msgstr "Boczny lewy"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Side Right"
+msgstr "Boczny prawy"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Auxiliary 0"
+msgstr "Pomocnicze 0"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Auxiliary 1"
+msgstr "Pomocnicze 1"
+
+#: ../src/pulse/channelmap.c:122
+msgid "Auxiliary 2"
+msgstr "Pomocnicze 2"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 3"
+msgstr "Pomocnicze 3"
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 4"
+msgstr "Pomocnicze 4"
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 5"
+msgstr "Pomocnicze 5"
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 6"
+msgstr "Pomocnicze 6"
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 7"
+msgstr "Pomocnicze 7"
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 8"
+msgstr "Pomocnicze 8"
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 9"
+msgstr "Pomocnicze 9"
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 10"
+msgstr "Pomocnicze 10"
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 11"
+msgstr "Pomocnicze 11"
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 12"
+msgstr "Pomocnicze 12"
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 13"
+msgstr "Pomocnicze 13"
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 14"
+msgstr "Pomocnicze 14"
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 15"
+msgstr "Pomocnicze 15"
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 16"
+msgstr "Pomocnicze 16"
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 17"
+msgstr "Pomocnicze 17"
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 18"
+msgstr "Pomocnicze 18"
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 19"
+msgstr "Pomocnicze 19"
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 20"
+msgstr "Pomocnicze 20"
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 21"
+msgstr "Pomocnicze 21"
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 22"
+msgstr "Pomocnicze 22"
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 23"
+msgstr "Pomocnicze 23"
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 24"
+msgstr "Pomocnicze 24"
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 25"
+msgstr "Pomocnicze 25"
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 26"
+msgstr "Pomocnicze 26"
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 27"
+msgstr "Pomocnicze 27"
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 28"
+msgstr "Pomocnicze 28"
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 29"
+msgstr "Pomocnicze 29"
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 30"
+msgstr "Pomocnicze 30"
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 31"
+msgstr "Pomocnicze 31"
+
+#: ../src/pulse/channelmap.c:153
+msgid "Top Center"
+msgstr "Górny środkowy"
+
+#: ../src/pulse/channelmap.c:155
+msgid "Top Front Center"
+msgstr "Górny przedni środkowy"
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Front Left"
+msgstr "Górny przedni lewy"
+
+#: ../src/pulse/channelmap.c:157
+msgid "Top Front Right"
+msgstr "Górny przedni prawy"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Rear Center"
+msgstr "Górny tylny środkowy"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Rear Left"
+msgstr "Górny tylny lewy"
+
+#: ../src/pulse/channelmap.c:161
+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"
+
+#: ../src/pulse/error.c:44
+msgid "Access denied"
+msgstr "Odmówiono dostępu"
+
+#: ../src/pulse/error.c:45
+msgid "Unknown command"
+msgstr "Nieznane polecenie"
+
+#: ../src/pulse/error.c:46
+msgid "Invalid argument"
+msgstr "Nieprawidłowy parametr"
+
+#: ../src/pulse/error.c:47
+msgid "Entity exists"
+msgstr "Jednostka istnieje"
+
+#: ../src/pulse/error.c:48
+msgid "No such entity"
+msgstr "Brak jednostki"
+
+#: ../src/pulse/error.c:49
+msgid "Connection refused"
+msgstr "Odrzucono połączenie"
+
+#: ../src/pulse/error.c:50
+msgid "Protocol error"
+msgstr "Błąd protokołu"
+
+#: ../src/pulse/error.c:51
+msgid "Timeout"
+msgstr "Przekroczono czas oczekiwania"
+
+#: ../src/pulse/error.c:52
+msgid "No authorization key"
+msgstr "Brak klucza upoważnienia"
+
+#: ../src/pulse/error.c:53
+msgid "Internal error"
+msgstr "Wewnętrzny błąd"
+
+#: ../src/pulse/error.c:54
+msgid "Connection terminated"
+msgstr "Zniszczono połączenie"
+
+#: ../src/pulse/error.c:55
+msgid "Entity killed"
+msgstr "Zniszczono jednostkę"
+
+#: ../src/pulse/error.c:56
+msgid "Invalid server"
+msgstr "Nieprawidłowy serwer"
+
+#: ../src/pulse/error.c:57
+msgid "Module initalization failed"
+msgstr "Zainicjowanie modułu nie powiodło się"
+
+#: ../src/pulse/error.c:58
+msgid "Bad state"
+msgstr "Błędny stan"
+
+#: ../src/pulse/error.c:59
+msgid "No data"
+msgstr "Brak danych"
+
+#: ../src/pulse/error.c:60
+msgid "Incompatible protocol version"
+msgstr "Niezgodna wersja protokołu"
+
+#: ../src/pulse/error.c:61
+msgid "Too large"
+msgstr "Za duże"
+
+#: ../src/pulse/error.c:62
+msgid "Not supported"
+msgstr "Nieobsługiwane"
+
+#: ../src/pulse/error.c:63
+msgid "Unknown error code"
+msgstr "Nieznany kod błędu"
+
+#: ../src/pulse/error.c:64
+msgid "No such extension"
+msgstr "Nie ma takiego rozszerzenia"
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
+msgid "XOpenDisplay() failed"
+msgstr "XOpenDisplay() nie powiodło się"
+
+#: ../src/pulse/client-conf-x11.c:78
+msgid "Failed to parse cookie data"
+msgstr "Analiza danych ciasteczka nie powiodło się"
+
+#: ../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"
+
+#: ../src/pulse/context.c:516
+msgid "No cookie loaded. Attempting to connect without."
+msgstr "Nie wczytano ciasteczka. Próbowanie połączenia się bez niego."
+
+#: ../src/pulse/context.c:642
+#, c-format
+msgid "fork(): %s"
+msgstr "fork(): %s"
+
+#: ../src/pulse/context.c:695
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid(): %s"
+
+#: ../src/pulse/context.c:1256
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr "Otrzymano komunikat z nieznanego powodu \"%s\""
+
+#: ../src/utils/pacat.c:93
+#, c-format
+msgid "pa_stream_write() failed: %s\n"
+msgstr "pa_stream_write() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:132
+#, c-format
+msgid "pa_stream_peek() failed: %s\n"
+msgstr "pa_stream_peek() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "Buffer overrun, dropping incoming data\n"
+msgstr "Przepełniono bufor, porzucanie danych przychodzących\n"
+
+#: ../src/utils/pacat.c:143
+#, c-format
+msgid "pa_stream_drop() failed: %s\n"
+msgstr "pa_stream_drop() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:169
+#, c-format
+msgid "Stream successfully created.\n"
+msgstr "Pomyślnie utworzono strumień.\n"
+
+#: ../src/utils/pacat.c:172
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s\n"
+msgstr "pa_stream_get_buffer_attr() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:176
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+msgstr "Metryka bufora: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+
+#: ../src/utils/pacat.c:179
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u\n"
+msgstr "Metryka bufora: maxlength=%u, fragsize=%u\n"
+
+#: ../src/utils/pacat.c:183
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'.\n"
+msgstr "Używanie przykładowej specyfikacji \"%s\", mapa kanałów \"%s\".\n"
+
+#: ../src/utils/pacat.c:187
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended).\n"
+msgstr "Połączono się z urządzeniem %s (%u, %swstrzymane).\n"
+
+#: ../src/utils/pacat.c:197
+#, c-format
+msgid "Stream error: %s\n"
+msgstr "Błąd strumienia: %s\n"
+
+#: ../src/utils/pacat.c:207
+#, c-format
+msgid "Stream device suspended.%s \n"
+msgstr "Wstrzymano urządzenie strumienia.%s \n"
+
+#: ../src/utils/pacat.c:209
+#, c-format
+msgid "Stream device resumed.%s \n"
+msgstr "Wznowiono urządzenie strumienia.%s \n"
+
+#: ../src/utils/pacat.c:217
+#, c-format
+msgid "Stream underrun.%s \n"
+msgstr "Niedopełniono strumień.%s \n"
+
+#: ../src/utils/pacat.c:224
+#, c-format
+msgid "Stream overrun.%s \n"
+msgstr "Przepełniono strumień.%s \n"
+
+#: ../src/utils/pacat.c:231
+#, c-format
+msgid "Stream started.%s \n"
+msgstr "Utworzono strumień.%s \n"
+
+#: ../src/utils/pacat.c:238
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s \n"
+msgstr "Strumień został przeniesiony do urządzenia %s (%u, %swstrzymane).%s \n"
+
+#: ../src/utils/pacat.c:238
+msgid "not "
+msgstr "nie "
+
+#: ../src/utils/pacat.c:259
+#, c-format
+msgid "Connection established.%s \n"
+msgstr "Ustanowiono połączenie.%s \n"
+
+#: ../src/utils/pacat.c:262
+#, c-format
+msgid "pa_stream_new() failed: %s\n"
+msgstr "pa_stream_new() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:287
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s\n"
+msgstr "pa_stream_connect_playback() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:293
+#, c-format
+msgid "pa_stream_connect_record() failed: %s\n"
+msgstr "pa_stream_connect_record() nie powiodło się: %s\n"
+
+#: ../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 "Połączenie nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:328 ../src/utils/paplay.c:75
+#, c-format
+msgid "Failed to drain stream: %s\n"
+msgstr "Opróżnienie strumienia nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:333 ../src/utils/paplay.c:80
+#, c-format
+msgid "Playback stream drained.\n"
+msgstr "Opróżniono strumień odtwarzania.\n"
+
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
+#, c-format
+msgid "Draining connection to server.\n"
+msgstr "Opróżnianie połączenia z serwerem.\n"
+
+#: ../src/utils/pacat.c:369
+#, c-format
+msgid "Got EOF.\n"
+msgstr "Otrzymano EOF.\n"
+
+#: ../src/utils/pacat.c:375
+#, c-format
+msgid "pa_stream_drain(): %s\n"
+msgstr "pa_stream_drain(): %s\n"
+
+#: ../src/utils/pacat.c:385
+#, c-format
+msgid "read() failed: %s\n"
+msgstr "read() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:417
+#, c-format
+msgid "write() failed: %s\n"
+msgstr "write() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:438
+#, c-format
+msgid "Got signal, exiting.\n"
+msgstr "Otrzymano sygnał, wyłączanie.\n"
+
+#: ../src/utils/pacat.c:452
+#, c-format
+msgid "Failed to get latency: %s\n"
+msgstr "Uzyskanie opóźnienia nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:457
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec. \r"
+msgstr "Czas: %0.3f sekundy; opóźnienie: %0.0f usekundy. \r"
+
+#: ../src/utils/pacat.c:477
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s\n"
+msgstr "pa_stream_update_timing_info() nie powiodło się: %s\n"
+
+#: ../src/utils/pacat.c:490
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -r, --record Create a connection for recording\n"
+" -p, --playback Create a connection for playback\n"
+"\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"
+" (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"
+" being connected to.\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"
+" --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"
+msgstr ""
+"%s [opcje]\n"
+"\n"
+" -h, --help Wyświetla tę pomoc\n"
+" --version Wyświetla wersję\n"
+"\n"
+" -r, --record Tworzy połączenie do nagrywania\n"
+" -p, --playback Tworzy połączenie do odtwarzania\n"
+"\n"
+" -v, --verbose Wyświetla więcej informacji o "
+"działaniu\n"
+"\n"
+" -s, --server=SERWER Nazwa serwera do połączenia się z\n"
+" -d, --device=URZĄDZENIE Nazwa odpływu/źródła do połączenia "
+"się z\n"
+" -n, --client-name=NAZWA Jak nazywać tego klienta na "
+"serwerze\n"
+" --stream-name=NAZWA Jak nazwać ten strumień na serwerze\n"
+" --volume=POZIOMGŁOŚNOŚCI Określa początkowy (liniowy) poziom "
+"głośności z zakresie 0...65536\n"
+" --rate=CZĘSTOTLIWOŚĆPRÓBKI Częstotliwość próbki w Hz (domyślnie "
+"44100)\n"
+" --format=FORMATPRÓBKI Typ próbki, jeden z s16le, s16be, "
+"u8, float32le,\n"
+" float32be, ulaw, alaw, s32le, s32be "
+"(domyślnie s16ne)\n"
+" --channels=KANAŁY Liczba kanałów, 1 dla mono, 2 dla "
+"stereo\n"
+" (domyślnie 2)\n"
+" --channel-map=MAPAKANAŁÓW Mapa kanałów używa zamiast "
+"domyślnej\n"
+" --fix-format Pobiera format próbki z odpływu, z "
+"jakim\n"
+" połączony jest strumień.\n"
+" --fix-rate Pobiera częstotliwość sampli z "
+"odpływu, z\n"
+" jakim połączony jest strumień.\n"
+" --fix-channels Pobiera liczbę kanałów i mapę "
+"kanałów z odpływu,\n"
+" z jakim połączony jest strumień.\n"
+" --no-remix Nie miesza kanałów w górę lub w "
+"dół.\n"
+" --no-remap Mapuje kanały przez indeks zamiast "
+"przez nazwę.\n"
+" --latency=BAJTY Żąda określonego opóźnienia w "
+"bajtach.\n"
+" --process-time=BAJTY Żąda określonego czasu procesu na "
+"żądanie w bajtach.\n"
+
+#: ../src/utils/pacat.c:591
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pacat %s\n"
+"Skompilowane za pomocą libpulse %s\n"
+"Skonsolidowane za pomocą libpulse %s\n"
+
+#: ../src/utils/pacat.c:647
+#, c-format
+msgid "Invalid channel map '%s'\n"
+msgstr "Nieprawidłowa mapa kanałów \"%s\"\n"
+
+#: ../src/utils/pacat.c:676
+#, c-format
+msgid "Invalid latency specification '%s'\n"
+msgstr "Nieprawidłowe określenie opóźnienia \"%s\"\n"
+
+#: ../src/utils/pacat.c:683
+#, c-format
+msgid "Invalid process time specification '%s'\n"
+msgstr "Nieprawidłowe określenie czasu procesu \"%s\"\n"
+
+#: ../src/utils/pacat.c:694
+#, c-format
+msgid "Invalid sample specification\n"
+msgstr "Nieprawidłowe określenie próbki\n"
+
+#: ../src/utils/pacat.c:699
+#, c-format
+msgid "Channel map doesn't match sample specification\n"
+msgstr "Mapa kanałów nie zgadza się z określeniem próbki\n"
+
+#: ../src/utils/pacat.c:706
+#, c-format
+msgid "Opening a %s stream with sample specification '%s'.\n"
+msgstr "Otwieranie strumienia %s za pomocą określenie próbki \"%s\".\n"
+
+#: ../src/utils/pacat.c:706
+msgid "recording"
+msgstr "nagrywanie"
+
+#: ../src/utils/pacat.c:706
+msgid "playback"
+msgstr "odtwarzanie"
+
+#: ../src/utils/pacat.c:714
+#, c-format
+msgid "open(): %s\n"
+msgstr "open(): %s\n"
+
+#: ../src/utils/pacat.c:719
+#, c-format
+msgid "dup2(): %s\n"
+msgstr "dup2(): %s\n"
+
+#: ../src/utils/pacat.c:729
+#, c-format
+msgid "Too many arguments.\n"
+msgstr "Za dużo parametrów.\n"
+
+#: ../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() nie powiodło się.\n"
+
+#: ../src/utils/pacat.c:763
+#, c-format
+msgid "io_new() failed.\n"
+msgstr "io_new() nie powiodło się.\n"
+
+#: ../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() nie powiodło się.\n"
+
+#: ../src/utils/pacat.c:777
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_connect() nie powiodło się: %s"
+
+#: ../src/utils/pacat.c:788
+#, c-format
+msgid "time_new() failed.\n"
+msgstr "time_new() nie powiodło się.\n"
+
+#: ../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() nie powiodło się.\n"
+
+#: ../src/utils/pasuspender.c:81
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork(): %s\n"
+
+#: ../src/utils/pasuspender.c:92
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp(): %s\n"
+
+#: ../src/utils/pasuspender.c:109
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr "Wstrzymanie nie powiodło się: %s\n"
+
+#: ../src/utils/pasuspender.c:124
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr "Wznowienie nie powiodło się: %s\n"
+
+#: ../src/utils/pasuspender.c:147
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr ""
+"OSTRZEŻENIE: serwer dźwięku nie jest lokalny, nie zostanie wstrzymany.\n"
+
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
+#: ../src/utils/paplay.c:191
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr "Otrzymano SIGINT, wyłączanie.\n"
+
+#: ../src/utils/pasuspender.c:194
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr "OSTRZEŻENIE: proces potomny został zniszczony przez sygnał %u\n"
+
+#: ../src/utils/pasuspender.c:212
+#, c-format
+msgid ""
+"%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"
+"\n"
+msgstr ""
+"%s [opcje] ... \n"
+"\n"
+" -h, --help Wyświetla tę pomoc\n"
+" --version Wyświetla wersję\n"
+" -s, --server=SERWER Nazwa serwera do połączenia się z\n"
+"\n"
+
+#: ../src/utils/pasuspender.c:251
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pasuspender %s\n"
+"Skompilowane za pomocą libpulse %s\n"
+"Skonsolidowane za pomocą libpulse %s\n"
+
+#: ../src/utils/pactl.c:107
+#, c-format
+msgid "Failed to get statistics: %s\n"
+msgstr "Uzyskanie statystyk nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:113
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr "Obecnie używane: %u bloków zawierających razem %s bajtów.\n"
+
+#: ../src/utils/pactl.c:116
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
+"Przydzielono podczas całego czasu uruchomienia: %u bloków zawierających "
+"razem %s bajtów.\n"
+
+#: ../src/utils/pactl.c:119
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr "Rozmiar pamięci podręcznej próbek: %s\n"
+
+#: ../src/utils/pactl.c:128
+#, c-format
+msgid "Failed to get server information: %s\n"
+msgstr "Uzyskanie informacji o serwerze nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:135
+#, c-format
+msgid ""
+"User name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %08x\n"
+msgstr ""
+"Nazwa użytkownika: %s\n"
+"Nazwa komputera: %s\n"
+"Nazwa serwera: %s\n"
+"Wersja serwera: %s\n"
+"Domyślne określenie próbki: %s\n"
+"Domyślny odpływ: %s\n"
+"Domyślne źródło: %s\n"
+"Ciasteczko: %08x\n"
+
+#: ../src/utils/pactl.c:160
+#, c-format
+msgid "Failed to get sink information: %s\n"
+msgstr "Uzyskanie informacji o odpływie nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"*** Sink #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor Source: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Odpływ #%u ***\n"
+"Nazwa: %s\n"
+"Sterownik: %s\n"
+"Określenie próbki: %s\n"
+"Mapa kanałów: %s\n"
+"Właściciel modułu: %u\n"
+"Poziom głośności: %s\n"
+"Źródło monitora: %s\n"
+"Opóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n"
+"Flagi: %s%s%s%s%s%s\n"
+"Właściwości:\n"
+"%s"
+
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
+msgid "muted"
+msgstr "wyciszone"
+
+#: ../src/utils/pactl.c:212
+#, c-format
+msgid "Failed to get source information: %s\n"
+msgstr "Uzyskanie informacji o źródle nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:228
+#, c-format
+msgid ""
+"*** Source #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor of Sink: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Źródło #%u ***\n"
+"Nazwa: %s\n"
+"Sterownik: %s\n"
+"Określenie próbki: %s\n"
+"Mapa kanałów: %s\n"
+"Właściciel modułu: %u\n"
+"Poziom głośności: %s\n"
+"Monitor odpływu: %s\n"
+"Opóźnienie: %0.0f usekundy, skonfigurowano %0.0f usekundy\n"
+"Flagi: %s%s%s%s%s%s\n"
+"Właściwości:\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
+msgid "n/a"
+msgstr "nie dotyczy"
+
+#: ../src/utils/pactl.c:263
+#, c-format
+msgid "Failed to get module information: %s\n"
+msgstr "Uzyskanie informacji o module nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:281
+#, c-format
+msgid ""
+"*** Module #%u ***\n"
+"Name: %s\n"
+"Argument: %s\n"
+"Usage counter: %s\n"
+"Auto unload: %s\n"
+msgstr ""
+"*** Moduł #%u ***\n"
+"Nazwa: %s\n"
+"Parametr: %s\n"
+"Liczniki użycia: %s\n"
+"Automatyczne usuwanie: %s\n"
+
+#: ../src/utils/pactl.c:298
+#, c-format
+msgid "Failed to get client information: %s\n"
+msgstr "Uzyskanie informacji o kliencie nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:316
+#, c-format
+msgid ""
+"*** Client #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Klient #%u ***\n"
+"Sterownik: %s\n"
+"Właściciel modułu: %s\n"
+"Właściwości:\n"
+"%s"
+
+#: ../src/utils/pactl.c:333
+#, c-format
+msgid "Failed to get sink input information: %s\n"
+msgstr "Uzyskanie informacji o wejściu odpływu nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:352
+#, c-format
+msgid ""
+"*** Sink Input #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Sink: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Volume: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Sink Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Odpływ wejścia #%u ***\n"
+"Sterownik: %s\n"
+"Właściciel modułu: %s\n"
+"Klient: %s\n"
+"Odpływ: %u\n"
+"Określenie próbki: %s\n"
+"Mapa kanałów: %s\n"
+"Poziom głośności: %s\n"
+"Opóźnienie bufora: %0.0f usekundy\n"
+"Opóźnienie odpływu: %0.0f usekundy\n"
+"Metoda resamplingu: %s\n"
+"Właściwości:\n"
+"%s"
+
+#: ../src/utils/pactl.c:385
+#, c-format
+msgid "Failed to get source output information: %s\n"
+msgstr "Uzyskanie informacji o wyjściu źródła nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:405
+#, c-format
+msgid ""
+"*** Source Output #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Source: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Source Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Źródło wyjścia #%u ***\n"
+"Sterownik: %s\n"
+"Właściciel modułu: %s\n"
+"Klient: %s\n"
+"Źródło: %u\n"
+"Określenie próbki: %s\n"
+"Mapa kanałów: %s\n"
+"Opóźnienie bufora: %0.0f usekundy\n"
+"Opóźnienie źródła: %0.0f usekundy\n"
+"Metoda resamplingu: %s\n"
+"Właściwości:\n"
+"%s"
+
+#: ../src/utils/pactl.c:436
+#, c-format
+msgid "Failed to get sample information: %s\n"
+msgstr "Uzyskanie informacji o przykładzie nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:455
+#, c-format
+msgid ""
+"*** Sample #%u ***\n"
+"Name: %s\n"
+"Volume: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Duration: %0.1fs\n"
+"Size: %s\n"
+"Lazy: %s\n"
+"Filename: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Próbka #%u ***\n"
+"Nazwa: %s\n"
+"Poziom głośności: %s\n"
+"Określenie próbki: %s\n"
+"Mapa kanałów: %s\n"
+"Czas trwania: %0.1fs\n"
+"Rozmiar: %s\n"
+"Lazy: %s\n"
+"Nazwa pliku: %s\n"
+"Właściwości:\n"
+"%s"
+
+#: ../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"
+
+#: ../src/utils/pactl.c:497
+#, c-format
+msgid ""
+"*** Autoload Entry #%u ***\n"
+"Name: %s\n"
+"Type: %s\n"
+"Module: %s\n"
+"Argument: %s\n"
+msgstr ""
+"*** Wpis automatycznego wczytywania #%u ***\n"
+"Nazwa: %s\n"
+"Typ: %s\n"
+"Moduł: %s\n"
+"Parametr: %s\n"
+
+#: ../src/utils/pactl.c:504
+msgid "sink"
+msgstr "odpływ"
+
+#: ../src/utils/pactl.c:504
+msgid "source"
+msgstr "źródło"
+
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
+#, c-format
+msgid "Failure: %s\n"
+msgstr "Niepowodzenie: %s\n"
+
+#: ../src/utils/pactl.c:545
+#, c-format
+msgid "Failed to upload sample: %s\n"
+msgstr "Usunięcie próbki nie powiodło się: %s\n"
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid "Premature end of file\n"
+msgstr "Przedwczesny koniec pliku\n"
+
+#: ../src/utils/pactl.c:678
+#, c-format
+msgid ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -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"
+msgstr ""
+"%s [opcje] stat\n"
+"%s [opcje] list\n"
+"%s [opcje] exit\n"
+"%s [opcje] upload-sample NAZWAPLIKU [NAZWA]\n"
+"%s [opcje] play-sample NAZWA [ODPŁYW]\n"
+"%s [opcje] remove-sample NAZWA\n"
+"%s [opcje] move-sink-input IDENTYFIKATOR ODPŁYW\n"
+"%s [opcje] move-source-output IDENTYFIKATOR ŹRÓDŁO\n"
+"%s [opcje] load-module NAZWA [PARAMETRY...]\n"
+"%s [opcje] unload-module IDENTYFIKATOR\n"
+"%s [opcje] suspend-sink [ODPŁYW] 1|0\n"
+"%s [opcje] suspend-source [ŹRÓDŁO] 1|0\n"
+"\n"
+" -h, --help Wyświetla tę pomoc\n"
+" --version Wyświetla wersję\n"
+"\n"
+" -s, --server=SERWER Nazwa serwera do połączenia się z\n"
+" -n, --client-name=NAZWA Jak nazwać tego klienta na serwerze\n"
+
+#: ../src/utils/pactl.c:729
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pactl %s\n"
+"Skompilowane za pomocą libpulse %s\n"
+"Skonsolidowane za pomocą libpulse %s\n"
+
+#: ../src/utils/pactl.c:768
+#, c-format
+msgid "Please specify a sample file to load\n"
+msgstr "Proszę podać plik próbki do wczytania\n"
+
+#: ../src/utils/pactl.c:790
+#, c-format
+msgid "Failed to open sound file.\n"
+msgstr "Otwarcie pliku dźwiękowego nie powiodło się.\n"
+
+#: ../src/utils/pactl.c:802
+#, c-format
+msgid "You have to specify a sample name to play\n"
+msgstr "Należy podać nazwę próbki do odtworzenia\n"
+
+#: ../src/utils/pactl.c:814
+#, c-format
+msgid "You have to specify a sample name to remove\n"
+msgstr "Należy podać nazwę próbki do usunięcia\n"
+
+#: ../src/utils/pactl.c:822
+#, c-format
+msgid "You have to specify a sink input index and a sink\n"
+msgstr "Należy podać indeks odpływu wejścia i odpływ\n"
+
+#: ../src/utils/pactl.c:831
+#, c-format
+msgid "You have to specify a source output index and a source\n"
+msgstr "Należy podać indeks źródła wyjścia i źródło\n"
+
+#: ../src/utils/pactl.c:845
+#, c-format
+msgid "You have to specify a module name and arguments.\n"
+msgstr "Należy podać nazwę modułu i parametry.\n"
+
+#: ../src/utils/pactl.c:865
+#, c-format
+msgid "You have to specify a module index\n"
+msgstr "Należy podać indeks modułu\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 ""
+"Nie można podać więcej niż jednego odpływu. Należy podać co najmniej jedną "
+"wartość logiczną.\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 ""
+"Nie można podać więcej niż jednego źródła. Należy podać co najmniej jedną "
+"wartość logiczną.\n"
+
+#: ../src/utils/pactl.c:904
+#, c-format
+msgid "No valid command specified.\n"
+msgstr "Nie podano prawidłowego polecenia.\n"
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%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"
+" -r Remove PulseAudio data from X11 display\n"
+msgstr ""
+"%s [-D ekran] [-S serwer] [-O odpływ] [-I źródło] [-c plik] [-d|-e|-i|-r]\n"
+"\n"
+" -d Wyświetla dane PulseAudio dołączone do ekranu X11 (domyślne)\n"
+" -e Eksportuje lokalne dane PulseAudio na ekran X11\n"
+" -i Importuje dane PulseAudio z ekranu X11 do lokalnych zmiennych "
+"środowiskowych i pliku ciasteczka.\n"
+" -r Usuwa dane PulseAudio z ekranu X11\n"
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "Analiza wiersza poleceń nie powiodła się.\n"
+
+#: ../src/utils/pax11publish.c:108
+#, c-format
+msgid "Server: %s\n"
+msgstr "Serwer: %s\n"
+
+#: ../src/utils/pax11publish.c:110
+#, c-format
+msgid "Source: %s\n"
+msgstr "Źródło: %s\n"
+
+#: ../src/utils/pax11publish.c:112
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Odpływ: %s\n"
+
+#: ../src/utils/pax11publish.c:114
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Ciasteczko: %s\n"
+
+#: ../src/utils/pax11publish.c:132
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr "Analiza danych ciasteczka nie powiodła się\n"
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr "Zapisanie danych ciasteczka nie powiodło się\n"
+
+#: ../src/utils/pax11publish.c:152
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr "Wczytanie pliku konfiguracji klienta nie powiodło się.\n"
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr "Odczytanie danych konfiguracji środowiska nie powiodło się.\n"
+
+#: ../src/utils/pax11publish.c:174
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr "Uzyskanie FQDN nie powiodło się.\n"
+
+#: ../src/utils/pax11publish.c:194
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr "Wczytanie danych ciasteczka nie powiodło się\n"
+
+#: ../src/utils/pax11publish.c:211
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "Niezaimplementowane.\n"
+
+#: ../src/utils/pacmd.c:64
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr "gniazdo(PF_UNIX, SOCK_STREAM, 0): %s"
+
+#: ../src/utils/pacmd.c:81
+#, c-format
+msgid "connect(): %s"
+msgstr "connect(): %s"
+
+#: ../src/utils/pacmd.c:89
+msgid "Failed to kill PulseAudio daemon."
+msgstr "Zniszczenie demona PulseAudio nie powiodło się."
+
+#: ../src/utils/pacmd.c:97
+msgid "Daemon not responding."
+msgstr "Demon nie odpowiada."
+
+#: ../src/utils/pacmd.c:112
+#, c-format
+msgid "select(): %s"
+msgstr "select(): %s"
+
+#: ../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
+#, c-format
+msgid "write(): %s"
+msgstr "write(): %s"
+
+#: ../src/utils/paplay.c:139
+#, c-format
+msgid "Stream successfully created\n"
+msgstr "Pomyślnie utworzono strumień\n"
+
+#: ../src/utils/paplay.c:144
+#, c-format
+msgid "Stream errror: %s\n"
+msgstr "Błąd strumienia: %s\n"
+
+#: ../src/utils/paplay.c:165
+#, c-format
+msgid "Connection established.\n"
+msgstr "Ustanowiono połączenie.\n"
+
+#: ../src/utils/paplay.c:198
+#, c-format
+msgid ""
+"%s [options] [FILE]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -v, --verbose Enable verbose operation\n"
+"\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"
+" --channel-map=CHANNELMAP Set the channel map to the use\n"
+msgstr ""
+"%s [opcje] [PLIK]\n"
+"\n"
+" -h, --help Wyświetla tę pomoc\n"
+" --version Wyświetla wersję\n"
+"\n"
+" -v, --verbose Wyświetla więcej informacji o "
+"działaniach\n"
+"\n"
+" -s, --server=SERWER Nazwa serwera do połączenia się z\n"
+" -d, --device=URZĄDZENIE Nazwa odpływu do połączenia się z\n"
+" -n, --client-name=NAZWA Jak nazwać tego klienta na serwerze\n"
+" --stream-name=NAZWA Jak nazwać ten strumień na serwerze\n"
+" --volume=POZIOMGŁOŚNOŚCI Określa początkowy (liniowy) poziom "
+"głośności w zakresie 0...65536\n"
+" --channel-map=MAPAKANAŁÓW Ustawia używaną mapę kanałów\n"
+
+#: ../src/utils/paplay.c:255
+#, c-format
+msgid ""
+"paplay %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"paplay %s\n"
+"Skompilowane za pomocą libpulse %s\n"
+"Skonsolidowane za pomocą libpulse %s\n"
+
+#: ../src/utils/paplay.c:292
+#, c-format
+msgid "Invalid channel map\n"
+msgstr "Nieprawidłowa mapa kanałów\n"
+
+#: ../src/utils/paplay.c:314
+#, c-format
+msgid "Failed to open file '%s'\n"
+msgstr "Otwarcie pliku \"%s\" nie powiodło się\n"
+
+#: ../src/utils/paplay.c:350
+#, c-format
+msgid "Channel map doesn't match file.\n"
+msgstr "Mapa kanałów nie zgadza się z plikiem.\n"
+
+#: ../src/utils/paplay.c:376
+#, c-format
+msgid "Using sample spec '%s'\n"
+msgstr "Używanie przykładowej specyfikacji \"%s\"\n"
+
+#: ../src/pulsecore/lock-autospawn.c:126 ../src/pulsecore/lock-autospawn.c:207
+msgid "Cannot access autospawn lock."
+msgstr "Nie można uzyskać dostępu do blokady automatycznego wznawiania."
diff --git a/po/pt_BR.po b/po/pt_BR.po
new file mode 100644
index 00000000..94494f7f
--- /dev/null
+++ b/po/pt_BR.po
@@ -0,0 +1,2130 @@
+# Brazilian Translation of PulseAudio
+# Copyright (C) 2008 pulseaudio
+# This file is distributed under the same license as the pulseaudio package.
+# Fabian Affolter <fab@fedoraproject.org>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pulseaudio\n"
+"Report-Msgid-Bugs-To: \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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"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
+msgid "Failed to add bind-now-loader."
+msgstr "Falha em adicionar o bind-now-loader."
+
+#: ../src/daemon/ltdl-bind-now.c:184
+msgid "Failed to find original dlopen loader."
+msgstr "Falha em encontrar o carregador original dlopen"
+
+#: ../src/daemon/polkit.c:55
+#, c-format
+msgid "Cannot connect to system bus: %s"
+msgstr "Não foi possível conectar com o barramento do sistema: %s"
+
+#: ../src/daemon/polkit.c:65
+#, c-format
+msgid "Cannot get caller from PID: %s"
+msgstr "Não foi possível obter quem chamou pelo PID: %s"
+
+#: ../src/daemon/polkit.c:77
+msgid "Cannot set UID on caller object."
+msgstr "Não foi possível definir o UID sobre o objeto que chamou."
+
+#: ../src/daemon/polkit.c:82
+msgid "Failed to get CK session."
+msgstr "Falha em obter a sessão CK."
+
+#: ../src/daemon/polkit.c:90
+msgid "Cannot set UID on session object."
+msgstr "Não foi possível definir o UID do objeto da sessão."
+
+#: ../src/daemon/polkit.c:95
+msgid "Cannot allocate PolKitAction."
+msgstr "Não foi possível alocar o PolKitAction."
+
+#: ../src/daemon/polkit.c:100
+msgid "Cannot set action_id"
+msgstr "Não foi possível definir a action_id"
+
+#: ../src/daemon/polkit.c:105
+msgid "Cannot allocate PolKitContext."
+msgstr "Não foi possível alocar o PolKitContext."
+
+#: ../src/daemon/polkit.c:110
+#, c-format
+msgid "Cannot initialize PolKitContext: %s"
+msgstr "Não foi possível iniciar o PolKitContext: %s"
+
+#: ../src/daemon/polkit.c:119
+#, c-format
+msgid "Could not determine whether caller is authorized: %s"
+msgstr "Não foi possível determinar se o solicitante está autorizado: %s"
+
+#: ../src/daemon/polkit.c:139
+#, c-format
+msgid "Cannot obtain auth: %s"
+msgstr "Não foi possível obter auth: %s"
+
+#: ../src/daemon/polkit.c:148
+#, c-format
+msgid "PolicyKit responded with '%s'"
+msgstr "PolicyKit respondeu com '%s'"
+
+#: ../src/daemon/main.c:134
+#, c-format
+msgid "Got signal %s."
+msgstr "Sinal %s recebido."
+
+#: ../src/daemon/main.c:161
+msgid "Exiting."
+msgstr "Saindo."
+
+#: ../src/daemon/main.c:179
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Falha em encontrar o usuário '%s'."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Falha em encontrar o grupo '%s'."
+
+#: ../src/daemon/main.c:188
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr "Usuário '%s' (UID %lu) e grupo '%s' (GID %lu) encontrados."
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr "O GID do usuário'%s' e do grupo '%s' não combinam."
+
+#: ../src/daemon/main.c:198
+#, c-format
+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
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "Falha em criar '%s': %s"
+
+#: ../src/daemon/main.c:213
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr "Falha em alterar a lista de grupos: %s"
+
+#: ../src/daemon/main.c:229
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr "Falha em mudar o GID: %s"
+
+#: ../src/daemon/main.c:245
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr "Falha em mudar o UID: %s"
+
+#: ../src/daemon/main.c:259
+msgid "Successfully dropped root privileges."
+msgstr "Os privilégios do root foram retirados com sucesso."
+
+#: ../src/daemon/main.c:267
+msgid "System wide mode unsupported on this platform."
+msgstr "O modo ampliado do sistema não tem suporte nessa plataforma."
+
+#: ../src/daemon/main.c:285
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) falhou: %s"
+
+#: ../src/daemon/main.c:425
+msgid "Failed to parse command line."
+msgstr "Falha em interpretar a linha de comando."
+
+#: ../src/daemon/main.c:441
+#, c-format
+msgid "We're in the group '%s', allowing high-priority scheduling."
+msgstr "Estamos no grupo '%s', permitindo escalonamento de alta prioridade."
+
+#: ../src/daemon/main.c:448
+#, c-format
+msgid "We're in the group '%s', allowing real-time scheduling."
+msgstr "Estamos no grupo '%s', permitindo escalonamento em tempo real."
+
+#: ../src/daemon/main.c:456
+msgid "PolicyKit grants us acquire-high-priority privilege."
+msgstr "O PolicyKit assegura-nos a aquisição de privilégio de alta prioridade."
+
+#: ../src/daemon/main.c:459
+msgid "PolicyKit refuses acquire-high-priority privilege."
+msgstr "O PolicyKit recusa a aquisição de privilégios de alta prioridade."
+
+#: ../src/daemon/main.c:464
+msgid "PolicyKit grants us acquire-real-time privilege."
+msgstr "O PolicyKit assegura-nos a aquisição de privilégios de tempo-real."
+
+#: ../src/daemon/main.c:467
+msgid "PolicyKit refuses acquire-real-time privilege."
+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"
+"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"
+"Não estamos no grupo'"
+
+#: ../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."
+
+#: ../src/daemon/main.c:522
+msgid "Successfully increased RLIMIT_RTPRIO"
+msgstr "RLIMIT_RTPRIO aumentado com sucesso"
+
+#: ../src/daemon/main.c:525
+#, c-format
+msgid "RLIMIT_RTPRIO failed: %s"
+msgstr "RLIMIT_RTPRIO falhou: %s"
+
+#: ../src/daemon/main.c:532
+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."
+
+#: ../src/daemon/main.c:597
+msgid "Daemon not running"
+msgstr "O daemon não está em execução"
+
+#: ../src/daemon/main.c:599
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr "Daemon executando como PID %u"
+
+#: ../src/daemon/main.c:609
+#, c-format
+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)."
+
+#: ../src/daemon/main.c:629
+msgid "Root priviliges required."
+msgstr "Privilégios de rot são requeridos."
+
+#: ../src/daemon/main.c:634
+msgid "--start not supported for system instances."
+msgstr "--start não tem suporte para instâncias de sistemas."
+
+#: ../src/daemon/main.c:639
+msgid "Running in system mode, but --disallow-exit not set!"
+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!"
+
+#: ../src/daemon/main.c:645
+msgid "Running in system mode, forcibly disabling SHM mode!"
+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!"
+
+#: ../src/daemon/main.c:677
+msgid "Failed to acquire stdio."
+msgstr "Falha em adquirir o stdio."
+
+#: ../src/daemon/main.c:683
+#, c-format
+msgid "pipe failed: %s"
+msgstr "O pipe falhou: %s"
+
+#: ../src/daemon/main.c:688
+#, c-format
+msgid "fork() failed: %s"
+msgstr "O fork() falhou: %s"
+
+#: ../src/daemon/main.c:702
+#, c-format
+msgid "read() failed: %s"
+msgstr "A operação read() falhou: %s"
+
+#: ../src/daemon/main.c:708
+msgid "Daemon startup failed."
+msgstr "Falha na partida do daemon."
+
+#: ../src/daemon/main.c:710
+msgid "Daemon startup successful."
+msgstr "Os daemons foram iniciados com sucesso."
+
+#: ../src/daemon/main.c:780
+#, c-format
+msgid "This is PulseAudio %s"
+msgstr "Este é o PulseAudio %s"
+
+#: ../src/daemon/main.c:781
+#, c-format
+msgid "Compilation host: %s"
+msgstr "Host de compilação: %s"
+
+#: ../src/daemon/main.c:782
+#, c-format
+msgid "Compilation CFLAGS: %s"
+msgstr "Compilação CFLAGS: %s"
+
+#: ../src/daemon/main.c:785
+#, c-format
+msgid "Running on host: %s"
+msgstr "Executando no host: %s"
+
+#: ../src/daemon/main.c:788
+#, c-format
+msgid "Page size is %lu bytes"
+msgstr "O tamanho da página é %lu bytes"
+
+#: ../src/daemon/main.c:791
+msgid "Compiled with Valgrind support: yes"
+msgstr "Compilado com suporte do Valgrind: sim"
+
+#: ../src/daemon/main.c:793
+msgid "Compiled with Valgrind support: no"
+msgstr "Compilado com suporte do Valgrind: não"
+
+#: ../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:801
+msgid "Optimized build: no"
+msgstr "Build otimizado: não"
+
+#: ../src/daemon/main.c:805
+msgid "Failed to get machine ID"
+msgstr "Falha em obter o ID da máquina"
+
+#: ../src/daemon/main.c:808
+#, c-format
+msgid "Machine ID is %s."
+msgstr "A ID da máquina é %s."
+
+#: ../src/daemon/main.c:813
+#, c-format
+msgid "Using runtime directory %s."
+msgstr "Usando o diretório de runtime %s."
+
+#: ../src/daemon/main.c:818
+#, c-format
+msgid "Using state directory %s."
+msgstr "Usando o diretório de estado %s."
+
+#: ../src/daemon/main.c:821
+#, c-format
+msgid "Running in system mode: %s"
+msgstr "Executando em modo do sistema: %s"
+
+#: ../src/daemon/main.c:836
+msgid "pa_pid_file_create() failed."
+msgstr "pa_pid_file_create() falhou."
+
+#: ../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: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:860
+msgid "pa_core_new() failed."
+msgstr "pa_core_new() falhou."
+
+#: ../src/daemon/main.c:921
+msgid "Failed to initialize daemon."
+msgstr "Falha em iniciar o daemon."
+
+#: ../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."
+
+#: ../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:944
+msgid "Daemon startup complete."
+msgstr "A partida dos Daemon está completa."
+
+#: ../src/daemon/main.c:950
+msgid "Daemon shutdown initiated."
+msgstr "O encerramento do Daemon foi iniciado."
+
+#: ../src/daemon/main.c:971
+msgid "Daemon terminated."
+msgstr "Daemon terminado."
+
+#: ../src/daemon/cmdline.c:117
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"COMMANDS:\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+" --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"
+" -k --kill Kill a running daemon\n"
+" --check Check for a running daemon\n"
+"\n"
+"OPTIONS:\n"
+" --system[=BOOL] Run as system-wide instance\n"
+" -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"
+" with elevated RLIMIT_NICE)\n"
+" --realtime[=BOOL] Try to enable realtime scheduling\n"
+" (only available as root, when SUID "
+"or\n"
+" with elevated RLIMIT_RTPRIO)\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"
+" time passed\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"
+" 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"
+" objects (plugins)\n"
+" --resample-method=METHOD Use the specified resampling method\n"
+" (See --dump-resample-methods for\n"
+" possible values)\n"
+" --use-pid-file[=BOOL] Create a PID file\n"
+" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
+" platforms that support it.\n"
+" --disable-shm[=BOOL] Disable shared memory support.\n"
+"\n"
+"STARTUP SCRIPT:\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"
+" after startup\n"
+"\n"
+" -n Don't load default script file\n"
+msgstr ""
+"%s [opções]\n"
+"\n"
+"COMANDOS:\n"
+" -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"
+" -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"
+" --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"
+" com RLIMIT_RTPRIO) elevado\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"
+" tempo foi decorrido\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"
+" este tempo tenha passado\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"
+" dinamicamente commpartilhados\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"
+" plataformas que o suportem.\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"
+" o argumento especificado\n"
+" -F, --file=FILENAME Executa o script especificado\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"
+
+#: ../src/daemon/cmdline.c:245
+msgid "--daemonize expects boolean argument"
+msgstr "--daemonize espera argumento booleano"
+
+#: ../src/daemon/cmdline.c:252
+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)."
+
+#: ../src/daemon/cmdline.c:274
+msgid "--high-priority expects boolean argument"
+msgstr "--high-priority espera um argumento booleano"
+
+#: ../src/daemon/cmdline.c:281
+msgid "--realtime expects boolean argument"
+msgstr "--realtime espera um argumento booleano"
+
+#: ../src/daemon/cmdline.c:288
+msgid "--disallow-module-loading expects boolean argument"
+msgstr "--disallow-module-loading espera um argumento booleano"
+
+#: ../src/daemon/cmdline.c:295
+msgid "--disallow-exit boolean argument"
+msgstr "--disallow-exit argumento booleano"
+
+#: ../src/daemon/cmdline.c:302
+msgid "--use-pid-file expects boolean argument"
+msgstr "--use-pid-file espera argumento booleano"
+
+#: ../src/daemon/cmdline.c:319
+msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+msgstr "Log target inválido: use 'syslog', 'stderr' ou 'auto'."
+
+#: ../src/daemon/cmdline.c:338
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr "Método de reamostragem inválido '%s'."
+
+#: ../src/daemon/cmdline.c:345
+msgid "--system expects boolean argument"
+msgstr "--system espera argumento booleano"
+
+#: ../src/daemon/cmdline.c:352
+msgid "--no-cpu-limit expects boolean argument"
+msgstr "--no-cpu-limit espera argumento booleano"
+
+#: ../src/daemon/cmdline.c:359
+msgid "--disable-shm expects boolean argument"
+msgstr "--disable-shm espera argumento booleano"
+
+#: ../src/daemon/dumpmodules.c:60
+#, c-format
+msgid "Name: %s\n"
+msgstr "Nome: %s\n"
+
+#: ../src/daemon/dumpmodules.c:63
+#, c-format
+msgid "No module information available\n"
+msgstr "Não há informação do módulo disponível\n"
+
+#: ../src/daemon/dumpmodules.c:66
+#, c-format
+msgid "Version: %s\n"
+msgstr "Versão: %s\n"
+
+#: ../src/daemon/dumpmodules.c:68
+#, c-format
+msgid "Description: %s\n"
+msgstr "Descrição: %s\n"
+
+#: ../src/daemon/dumpmodules.c:70
+#, c-format
+msgid "Author: %s\n"
+msgstr "Autor: %s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Usage: %s\n"
+msgstr "Uso: %s\n"
+
+#: ../src/daemon/dumpmodules.c:73
+#, c-format
+msgid "Load Once: %s\n"
+msgstr "Carrega uma vez: %s\n"
+
+#: ../src/daemon/dumpmodules.c:77
+#, c-format
+msgid "Path: %s\n"
+msgstr "Caminho: %s\n"
+
+#: ../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: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: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:260
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr "[%s:%u] rlimit inválido '%s'."
+
+#: ../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:283
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr "[%s:%u] Formato de amostragem inválido '%s'."
+
+#: ../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:319
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr "[%s:%u] Canais de amostragem inválidos'%s'."
+
+#: ../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:355
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr "[%s:%u] Tamanho de fragmentos inválido '%s'."
+
+#: ../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: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:644
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr "### Lido do arquivo de configuração: %s ###\n"
+
+#: ../src/daemon/caps.c:63
+msgid "Dropping root priviliges."
+msgstr "Descartando os privilégios de root."
+
+#: ../src/daemon/caps.c:103
+msgid "Limited capabilities successfully to CAP_SYS_NICE."
+msgstr "As capacidades foram limitadas com sucesso para CAP_SYS_NICE."
+
+#: ../src/pulse/channelmap.c:102
+msgid "Mono"
+msgstr "Mono"
+
+#: ../src/pulse/channelmap.c:104
+msgid "Front Center"
+msgstr "Fronto-cental"
+
+#: ../src/pulse/channelmap.c:105
+msgid "Front Left"
+msgstr "Frontal esquerdo"
+
+#: ../src/pulse/channelmap.c:106
+msgid "Front Right"
+msgstr "Frontal direito"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Rear Center"
+msgstr "Posterior central"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Rear Left"
+msgstr "Posterior esquerdo"
+
+#: ../src/pulse/channelmap.c:110
+msgid "Rear Right"
+msgstr "Posterior direito"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Low Frequency Emmiter"
+msgstr "Emissor de baixa freqüência"
+
+#: ../src/pulse/channelmap.c:114
+msgid "Front Left-of-center"
+msgstr "Frontal Esquerdo do centro"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Front Right-of-center"
+msgstr "Frontal Direito do centro"
+
+#: ../src/pulse/channelmap.c:117
+msgid "Side Left"
+msgstr "Lateral esquedo"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Side Right"
+msgstr "Lateral direito"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Auxiliary 0"
+msgstr "Auxiliar 0"
+
+#: ../src/pulse/channelmap.c:121
+msgid "Auxiliary 1"
+msgstr "Auxiliar 1"
+
+#: ../src/pulse/channelmap.c:122
+msgid "Auxiliary 2"
+msgstr "Auxiliar 2"
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 3"
+msgstr "Auxiliar 3"
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 4"
+msgstr "Auxiliar 4"
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 5"
+msgstr "Auxiliar 5"
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 6"
+msgstr "Auxiliar 6"
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 7"
+msgstr "Auxiliar 7"
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 8"
+msgstr "Auxiliar 8"
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 9"
+msgstr "Auxiliar 9"
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 10"
+msgstr "Auxiliar 10"
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 11"
+msgstr "Auxiliar 11"
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 12"
+msgstr "Auxiliar 12"
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 13"
+msgstr "Auxiliar13"
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 14"
+msgstr "Auxiliar 14"
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 15"
+msgstr "Auxiliar 15"
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 16"
+msgstr "Auxiliar 16"
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 17"
+msgstr "Auxiliar 17"
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 18"
+msgstr "Auxiliar 18"
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 19"
+msgstr "Auxiliar 19"
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 20"
+msgstr "Auxiliar 20"
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 21"
+msgstr "Auxiliar 21"
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 22"
+msgstr "Auxiliar 22"
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 23"
+msgstr "Auxiliar 23"
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 24"
+msgstr "Auxiliar 24"
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 25"
+msgstr "Auxiliar 25"
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 26"
+msgstr "Auxiliar 26"
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 27"
+msgstr "Auxiliar 26"
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 28"
+msgstr "Auxiliar 28"
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 29"
+msgstr "Auxiliar 29"
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 30"
+msgstr "Auxiliar 30"
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 31"
+msgstr "Auxiliar 31"
+
+#: ../src/pulse/channelmap.c:153
+msgid "Top Center"
+msgstr "Central Superior"
+
+#: ../src/pulse/channelmap.c:155
+msgid "Top Front Center"
+msgstr "Central Frontal Superior"
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Front Left"
+msgstr "Frontal Superior Esquerdo"
+
+#: ../src/pulse/channelmap.c:157
+msgid "Top Front Right"
+msgstr "Fontal Superior Direito"
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Rear Center"
+msgstr "Central Superior Posterior"
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Rear Left"
+msgstr "Posterior Superior Esquerdo"
+
+#: ../src/pulse/channelmap.c:161
+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"
+
+#: ../src/pulse/error.c:44
+msgid "Access denied"
+msgstr "Acesso Negado"
+
+#: ../src/pulse/error.c:45
+msgid "Unknown command"
+msgstr "Comando desconhecido"
+
+#: ../src/pulse/error.c:46
+msgid "Invalid argument"
+msgstr "Argumento inválido"
+
+#: ../src/pulse/error.c:47
+msgid "Entity exists"
+msgstr "Entidade existente"
+
+#: ../src/pulse/error.c:48
+msgid "No such entity"
+msgstr "Não existe tal entidade"
+
+#: ../src/pulse/error.c:49
+msgid "Connection refused"
+msgstr "Conexão recusada"
+
+#: ../src/pulse/error.c:50
+msgid "Protocol error"
+msgstr "Erro de protocolo"
+
+#: ../src/pulse/error.c:51
+msgid "Timeout"
+msgstr "Timeout"
+
+#: ../src/pulse/error.c:52
+msgid "No authorization key"
+msgstr "Não há chave para autorização"
+
+#: ../src/pulse/error.c:53
+msgid "Internal error"
+msgstr "Erro interno"
+
+#: ../src/pulse/error.c:54
+msgid "Connection terminated"
+msgstr "Conexão terminada"
+
+#: ../src/pulse/error.c:55
+msgid "Entity killed"
+msgstr "Entidade terminada"
+
+#: ../src/pulse/error.c:56
+msgid "Invalid server"
+msgstr "Servidor inválido"
+
+#: ../src/pulse/error.c:57
+msgid "Module initalization failed"
+msgstr "A inicialização do módulo falhou"
+
+#: ../src/pulse/error.c:58
+msgid "Bad state"
+msgstr "Mau estado"
+
+#: ../src/pulse/error.c:59
+msgid "No data"
+msgstr "Não há dados"
+
+#: ../src/pulse/error.c:60
+msgid "Incompatible protocol version"
+msgstr "Versão de protocolo incompatível"
+
+#: ../src/pulse/error.c:61
+msgid "Too large"
+msgstr "Muito grande"
+
+#: ../src/pulse/error.c:62
+msgid "Not supported"
+msgstr "Não há suporte"
+
+#: ../src/pulse/error.c:63
+msgid "Unknown error code"
+msgstr "Código de erro desconhecido"
+
+#: ../src/pulse/error.c:64
+msgid "No such extension"
+msgstr "Não existe tal extensão"
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
+msgid "XOpenDisplay() failed"
+msgstr "XOpenDisplay() falhou"
+
+#: ../src/pulse/client-conf-x11.c:78
+msgid "Failed to parse cookie data"
+msgstr "Falhou ao analisar os dados do cookie"
+
+#: ../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"
+
+#: ../src/pulse/context.c:516
+msgid "No cookie loaded. Attempting to connect without."
+msgstr "Nenhum cookie foi carregado. Tentativa de conexão sem eles."
+
+#: ../src/pulse/context.c:642
+#, c-format
+msgid "fork(): %s"
+msgstr "fork(): %s"
+
+#: ../src/pulse/context.c:695
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid(): %s"
+
+#: ../src/pulse/context.c:1256
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr "Foi recebida uma mensagem para uma extensão desconhecida '%s'"
+
+#: ../src/utils/pacat.c:93
+#, c-format
+msgid "pa_stream_write() failed: %s\n"
+msgstr "pa_stream_write() falhou: %s\n"
+
+#: ../src/utils/pacat.c:132
+#, c-format
+msgid "pa_stream_peek() failed: %s\n"
+msgstr "pa_stream_peek() falhou: %s\n"
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "Buffer overrun, dropping incoming data\n"
+msgstr "Houve estouro de buffer, os dados que chegaram foram descartados\n"
+
+#: ../src/utils/pacat.c:143
+#, c-format
+msgid "pa_stream_drop() failed: %s\n"
+msgstr "pa_stream_drop() falhou: %s\n"
+
+#: ../src/utils/pacat.c:169
+#, c-format
+msgid "Stream successfully created.\n"
+msgstr "O fluxo (stream) foi criado com sucesso.\n"
+
+#: ../src/utils/pacat.c:172
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s\n"
+msgstr "pa_stream_get_buffer_attr() falhou: %s\n"
+
+#: ../src/utils/pacat.c:176
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+msgstr "Metrica do buffer: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+
+#: ../src/utils/pacat.c:179
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u\n"
+msgstr "Métrica do buffer: maxlength=%u, fragsize=%u\n"
+
+#: ../src/utils/pacat.c:183
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'.\n"
+msgstr "Usando a espeficifação de amostragem '%s', mapa do canal '%s'.\n"
+
+#: ../src/utils/pacat.c:187
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended).\n"
+msgstr "Conectado ao dispositivo %s (%u, %ssuspended).\n"
+
+#: ../src/utils/pacat.c:197
+#, c-format
+msgid "Stream error: %s\n"
+msgstr "Erro de fluxo: %s\n"
+
+#: ../src/utils/pacat.c:207
+#, c-format
+msgid "Stream device suspended.%s \n"
+msgstr "Dispositivo de fluxo suspenso.%s \n"
+
+#: ../src/utils/pacat.c:209
+#, c-format
+msgid "Stream device resumed.%s \n"
+msgstr "Dispositivo de fluxo prosseguiu.%s \n"
+
+#: ../src/utils/pacat.c:217
+#, c-format
+msgid "Stream underrun.%s \n"
+msgstr "Extravazamento do fluxo. %s\n"
+
+#: ../src/utils/pacat.c:224
+#, c-format
+msgid "Stream overrun.%s \n"
+msgstr "O fluxo extravazou.%s \n"
+
+#: ../src/utils/pacat.c:231
+#, c-format
+msgid "Stream started.%s \n"
+msgstr "O fluxo iniciou: %s\n"
+
+#: ../src/utils/pacat.c:238
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s \n"
+msgstr "O fluxo foi movido para o dispositivo %s (%u, %ssuspended).%s \n"
+
+#: ../src/utils/pacat.c:238
+msgid "not "
+msgstr "não"
+
+#: ../src/utils/pacat.c:259
+#, c-format
+msgid "Connection established.%s \n"
+msgstr "Conexão estabelecida.%s \n"
+
+#: ../src/utils/pacat.c:262
+#, c-format
+msgid "pa_stream_new() failed: %s\n"
+msgstr "pa_stream_new() falhou: %s\n"
+
+#: ../src/utils/pacat.c:287
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s\n"
+msgstr "pa_stream_connect_playback() falhou: %s\n"
+
+#: ../src/utils/pacat.c:293
+#, c-format
+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
+#, c-format
+msgid "Connection failure: %s\n"
+msgstr "Falha na conexão: %s\n"
+
+#: ../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
+#, c-format
+msgid "Playback stream drained.\n"
+msgstr "Drenado o fluxo de playback.\n"
+
+#: ../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"
+
+#: ../src/utils/pacat.c:369
+#, c-format
+msgid "Got EOF.\n"
+msgstr "Atingiu EOF.\n"
+
+#: ../src/utils/pacat.c:375
+#, c-format
+msgid "pa_stream_drain(): %s\n"
+msgstr "pa_stream_drain(): %s\n"
+
+#: ../src/utils/pacat.c:385
+#, c-format
+msgid "read() failed: %s\n"
+msgstr "read() falhou: %s\n"
+
+#: ../src/utils/pacat.c:417
+#, c-format
+msgid "write() failed: %s\n"
+msgstr "write() falhou: %s\n"
+
+#: ../src/utils/pacat.c:438
+#, c-format
+msgid "Got signal, exiting.\n"
+msgstr "Sinal recebido, saindo (exiting).\n"
+
+#: ../src/utils/pacat.c:452
+#, c-format
+msgid "Failed to get latency: %s\n"
+msgstr "Falhou em obter a latência: %s\n"
+
+#: ../src/utils/pacat.c:457
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec. \r"
+msgstr "Tempo: %0.3f s; Latência: %0.0f us. \r"
+
+#: ../src/utils/pacat.c:477
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s\n"
+msgstr "Falha em pa_stream_update_timing_info(): %s\n"
+
+#: ../src/utils/pacat.c:490
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -r, --record Create a connection for recording\n"
+" -p, --playback Create a connection for playback\n"
+"\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"
+" (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"
+" being connected to.\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"
+" --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"
+msgstr ""
+"%s [opções]\n"
+"\n"
+" -h, --help Mostra essa ajuda\n"
+" --version Mostra a versão\n"
+"\n"
+" -r, --record Cria uma conexão para gravação\n"
+" -p, --playback Cria uma conexão para playback\n"
+"\n"
+" -v, --verbose Habilita operações no modo verboso\n"
+"\n"
+" -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"
+" (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"
+" está sendo conectado.\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"
+" --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"
+
+#: ../src/utils/pacat.c:591
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pacat %s\n"
+"Compilado com libpulse %s\n"
+"Linkado com libpulse %s\n"
+
+#: ../src/utils/pacat.c:647
+#, c-format
+msgid "Invalid channel map '%s'\n"
+msgstr "Mapa de canal inválido '%s'\n"
+
+#: ../src/utils/pacat.c:676
+#, c-format
+msgid "Invalid latency specification '%s'\n"
+msgstr "Especificação de latência inválida '%s'\n"
+
+#: ../src/utils/pacat.c:683
+#, c-format
+msgid "Invalid process time specification '%s'\n"
+msgstr "Especificação do tempo do processo inválida '%s'\n"
+
+#: ../src/utils/pacat.c:694
+#, c-format
+msgid "Invalid sample specification\n"
+msgstr "Especificação de amostragem inválida\n"
+
+#: ../src/utils/pacat.c:699
+#, c-format
+msgid "Channel map doesn't match sample specification\n"
+msgstr "O mapeamento do canal não casa com a especificação da amostragem\n"
+
+#: ../src/utils/pacat.c:706
+#, c-format
+msgid "Opening a %s stream with sample specification '%s'.\n"
+msgstr "Abrindo um %s fluxo com a especificação de amostragem '%s'.\n"
+
+#: ../src/utils/pacat.c:706
+msgid "recording"
+msgstr "gravando"
+
+#: ../src/utils/pacat.c:706
+msgid "playback"
+msgstr "playback"
+
+#: ../src/utils/pacat.c:714
+#, c-format
+msgid "open(): %s\n"
+msgstr "open(): %s\n"
+
+#: ../src/utils/pacat.c:719
+#, c-format
+msgid "dup2(): %s\n"
+msgstr "dup2(): %s\n"
+
+#: ../src/utils/pacat.c:729
+#, c-format
+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
+#, c-format
+msgid "pa_mainloop_new() failed.\n"
+msgstr "pa_mainloop_new() falhou.\n"
+
+#: ../src/utils/pacat.c:763
+#, c-format
+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
+#, c-format
+msgid "pa_context_new() failed.\n"
+msgstr "pa_context_new() falhou.\n"
+
+#: ../src/utils/pacat.c:777
+#, c-format
+msgid "pa_context_connect() failed: %s"
+msgstr "pa_context_new() falhou: %s"
+
+#: ../src/utils/pacat.c:788
+#, c-format
+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
+#, c-format
+msgid "pa_mainloop_run() failed.\n"
+msgstr "pa_mainloop_run() falhou.\n"
+
+#: ../src/utils/pasuspender.c:81
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork(): %s\n"
+
+#: ../src/utils/pasuspender.c:92
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp(): %s\n"
+
+#: ../src/utils/pasuspender.c:109
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr "Falha em suspender: %s\n"
+
+#: ../src/utils/pasuspender.c:124
+#, c-format
+msgid "Failure to resume: %s\n"
+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"
+
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
+#: ../src/utils/paplay.c:191
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr "Recebido o SIGINT, saindo.\n"
+
+#: ../src/utils/pasuspender.c:194
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr "AVISO: O processo filho terminou pelo sinal %u \n"
+
+#: ../src/utils/pasuspender.c:212
+#, c-format
+msgid ""
+"%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"
+"\n"
+msgstr ""
+"%s [options] ... \n"
+"\n"
+" -h, --help Mostra esta ajuda\n"
+" --version Mostra a versão\n"
+" -s, --server=SERVER Nome do servidor a ser conectado\n"
+"\n"
+
+#: ../src/utils/pasuspender.c:251
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pasuspender %s\n"
+"Compilado com libpulse %s\n"
+"Linkado com libpulse %s\n"
+
+#: ../src/utils/pactl.c:107
+#, c-format
+msgid "Failed to get statistics: %s\n"
+msgstr "Falha em obter as estatísticas: %s\n"
+
+#: ../src/utils/pactl.c:113
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr "Em uso no momento: %u blocos contendo %s bytes no total.\n"
+
+#: ../src/utils/pactl.c:116
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr "Alocado por todo o tempo: %u blocos contendo %s bytes no total.\n"
+
+#: ../src/utils/pactl.c:119
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr "Tamanho do cache para amostragem: %s\n"
+
+#: ../src/utils/pactl.c:128
+#, c-format
+msgid "Failed to get server information: %s\n"
+msgstr "Falha em obter a informação do servidor: %s\n"
+
+#: ../src/utils/pactl.c:135
+#, c-format
+msgid ""
+"User name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %08x\n"
+msgstr ""
+"Nome do Usuário: %s\n"
+"Nome do Host: %s\n"
+"Nome do Servidor: %s\n"
+"Versão do Servidor: %s\n"
+"Especificação padrão de amostragem: %s\n"
+"Destino padrão: %s\n"
+"Fonte padrão %s\n"
+"Cookie: %08x\n"
+
+#: ../src/utils/pactl.c:160
+#, c-format
+msgid "Failed to get sink information: %s\n"
+msgstr "Falha em obter a informação do destino: %s\n"
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"*** Sink #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor Source: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Destino #%u ***\n"
+"Nome: %s\n"
+"Driver: %s\n"
+"Especificação de amostragem: %s\n"
+"Mapa de canais: %s\n"
+"Propretário do módulo: %u\n"
+"Volume: %s\n"
+"Fonte do monitor: %s\n"
+"Latência: %0.0f us, configurado %0.0f us\n"
+"Flags: %s%s%s%s%s%s\n"
+"Propriedades:\n"
+"%s"
+
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
+msgid "muted"
+msgstr "mudo"
+
+#: ../src/utils/pactl.c:212
+#, c-format
+msgid "Failed to get source information: %s\n"
+msgstr "Falha em obter a informação da fonte: %s\n"
+
+#: ../src/utils/pactl.c:228
+#, c-format
+msgid ""
+"*** Source #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor of Sink: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Fonte #%u ***\n"
+"Nome: %s\n"
+"Driver: %s\n"
+"Especificação de amostragem: %s\n"
+"Mapa do canal: %s\n"
+"Proprietário do módulo: %u\n"
+"Volume: %s\n"
+"Monitor do destino: %s\n"
+"Latência: %0.0f us, configurado %0.0f us:\n"
+"Flags: %s%s%s%s%s%s\n"
+"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
+msgid "n/a"
+msgstr "n/a"
+
+#: ../src/utils/pactl.c:263
+#, c-format
+msgid "Failed to get module information: %s\n"
+msgstr "Falha em obter a informação do módulo: %s\n"
+
+#: ../src/utils/pactl.c:281
+#, c-format
+msgid ""
+"*** Module #%u ***\n"
+"Name: %s\n"
+"Argument: %s\n"
+"Usage counter: %s\n"
+"Auto unload: %s\n"
+msgstr ""
+"*** Módulo #%u ***\n"
+"Nome: %s\n"
+"Argumento: %s\n"
+"Contador de uso: %s\n"
+"Auto descarregar: %s\n"
+
+#: ../src/utils/pactl.c:298
+#, c-format
+msgid "Failed to get client information: %s\n"
+msgstr "Falhou ao obter a informação do cliente: %s\n"
+
+#: ../src/utils/pactl.c:316
+#, c-format
+msgid ""
+"*** Client #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Cliente #%u ***\n"
+"Driver: %s\n"
+"Poprietário do módulo: %s\n"
+"Propriedades:\n"
+"%s"
+
+#: ../src/utils/pactl.c:333
+#, c-format
+msgid "Failed to get sink input information: %s\n"
+msgstr "Falha na obtenção da informação de entrada do destino: %s\n"
+
+#: ../src/utils/pactl.c:352
+#, c-format
+msgid ""
+"*** Sink Input #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Sink: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Volume: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Sink Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Entrada do destino #%u ***\n"
+"Driver: %s\n"
+"Proprietário do módulo: %s\n"
+"Cliente: %s\n"
+"Destino: %u\n"
+"Especificação da amostragem: %s\n"
+"Mapa de canais: %s\n"
+"Volume: %s\n"
+"Latência do buffer: %0.0f us\n"
+"Latência do destino %0.0f usec\n"
+"Método de reamostragem (resample): %s\n"
+"Propriedades:\n"
+"%s"
+
+#: ../src/utils/pactl.c:385
+#, c-format
+msgid "Failed to get source output information: %s\n"
+msgstr "Falha em obter informações sobre a saída da fonte: %s\n"
+
+#: ../src/utils/pactl.c:405
+#, c-format
+msgid ""
+"*** Source Output #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Source: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Source Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Saída da Fonte #%u ***\n"
+"Driver: %s\n"
+"Proprietário do Módulo: %s\n"
+"Cliente: %s\n"
+"Fonte: %u\n"
+"Especificação de Amostragem: %s\n"
+"Mapa do Canal: %s\n"
+"Latência do Buffer: %0.0f usec\n"
+"Latência da Fonte: %0.0f usec\n"
+"Método de Reamostragem (resample): %s\n"
+"Propriedades:\n"
+"%s"
+
+#: ../src/utils/pactl.c:436
+#, c-format
+msgid "Failed to get sample information: %s\n"
+msgstr "Falha em obter informações sobre a amostragem: %s\n"
+
+#: ../src/utils/pactl.c:455
+#, c-format
+msgid ""
+"*** Sample #%u ***\n"
+"Name: %s\n"
+"Volume: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Duration: %0.1fs\n"
+"Size: %s\n"
+"Lazy: %s\n"
+"Filename: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+"*** Amostragem #%u ***\n"
+"Nome: %s\n"
+"Volume: %s\n"
+"Especificação da Amostragem: %s\n"
+"Mapa de Canais: %s\n"
+"Duração: %0.1fs\n"
+"Tamanho: %s\n"
+"Lazy: %s\n"
+"Nome do Arquivo: %s\n"
+"Propriedades:\n"
+"%s"
+
+#: ../src/utils/pactl.c:481
+#, c-format
+msgid "Failed to get autoload information: %s\n"
+msgstr "Falha em obter a informação do autoload: %s\n"
+
+#: ../src/utils/pactl.c:497
+#, c-format
+msgid ""
+"*** Autoload Entry #%u ***\n"
+"Name: %s\n"
+"Type: %s\n"
+"Module: %s\n"
+"Argument: %s\n"
+msgstr ""
+"*** Entrada do Autoload #%u ***\n"
+"Nome: %s\n"
+"Tipo: %s\n"
+"Módulo: %s\n"
+"Argumento: %s\n"
+
+#: ../src/utils/pactl.c:504
+msgid "sink"
+msgstr "destino"
+
+#: ../src/utils/pactl.c:504
+msgid "source"
+msgstr "fonte"
+
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
+#, c-format
+msgid "Failure: %s\n"
+msgstr "Falha: %s\n"
+
+#: ../src/utils/pactl.c:545
+#, c-format
+msgid "Failed to upload sample: %s\n"
+msgstr "Falha em carregar a amostra: %s\n"
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid "Premature end of file\n"
+msgstr "Fim prematuro do arquivo\n"
+
+#: ../src/utils/pactl.c:678
+#, c-format
+msgid ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -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"
+msgstr ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -h, --help Mostra essa ajuda\n"
+" --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"
+
+#: ../src/utils/pactl.c:729
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pactl %s\n"
+"Compilado com libpulse %s\n"
+"Linkado com libpulse %s\n"
+
+#: ../src/utils/pactl.c:768
+#, c-format
+msgid "Please specify a sample file to load\n"
+msgstr "Por favor, especifique o arquivo de amostra a ser carregado\n"
+
+#: ../src/utils/pactl.c:790
+#, c-format
+msgid "Failed to open sound file.\n"
+msgstr "Falha em abrir o arquivo de som.\n"
+
+#: ../src/utils/pactl.c:802
+#, c-format
+msgid "You have to specify a sample name to play\n"
+msgstr "Você deve especificar um nome da amostra para ser executada\n"
+
+#: ../src/utils/pactl.c:814
+#, c-format
+msgid "You have to specify a sample name to remove\n"
+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"
+
+#: ../src/utils/pactl.c:831
+#, c-format
+msgid "You have to specify a source output index and a source\n"
+msgstr "Você tem que especificar um índice de saída da fonte e uma fonte\n"
+
+#: ../src/utils/pactl.c:845
+#, c-format
+msgid "You have to specify a module name and arguments.\n"
+msgstr "Você deve especificar um nome do módulo e seus argumentos\n"
+
+#: ../src/utils/pactl.c:865
+#, c-format
+msgid "You have to specify a module index\n"
+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"
+
+#: ../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"
+
+#: ../src/utils/pactl.c:904
+#, c-format
+msgid "No valid command specified.\n"
+msgstr "Nenhum comando válido especificado.\n"
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%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"
+" -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"
+" -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"
+" -r Remove os dados do PulseAudio do display X11\n"
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "Falha em interpretar a linha de comando.\n"
+
+#: ../src/utils/pax11publish.c:108
+#, c-format
+msgid "Server: %s\n"
+msgstr "Servidor: %s\n"
+
+#: ../src/utils/pax11publish.c:110
+#, c-format
+msgid "Source: %s\n"
+msgstr "Fonte: %s\n"
+
+#: ../src/utils/pax11publish.c:112
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Destino: %s\n"
+
+#: ../src/utils/pax11publish.c:114
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Cookie: %s\n"
+
+#: ../src/utils/pax11publish.c:132
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr "Falha ao analisar os dados do cookie\n"
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr "Falha em salvar os dados do cookie\n"
+
+#: ../src/utils/pax11publish.c:152
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr "Falha em carregar o arquivo de configuração do cliente.\n"
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr "Falha em ler os dados de configuração do ambiente\n"
+
+#: ../src/utils/pax11publish.c:174
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr "Falha na obtenção do FQDN.\n"
+
+#: ../src/utils/pax11publish.c:194
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr "Falha em carregar os dados do cookie\n"
+
+#: ../src/utils/pax11publish.c:211
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "Ainda não implementado.\n"
+
+#: ../src/utils/pacmd.c:64
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+
+#: ../src/utils/pacmd.c:81
+#, c-format
+msgid "connect(): %s"
+msgstr "connect(): %s"
+
+#: ../src/utils/pacmd.c:89
+msgid "Failed to kill PulseAudio daemon."
+msgstr "Falha em cancelar o daemon do PulseAudio."
+
+#: ../src/utils/pacmd.c:97
+msgid "Daemon not responding."
+msgstr "Daemon não responde."
+
+#: ../src/utils/pacmd.c:112
+#, c-format
+msgid "select(): %s"
+msgstr "select(): %s"
+
+#: ../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
+#, c-format
+msgid "write(): %s"
+msgstr "write(): %s"
+
+#: ../src/utils/paplay.c:139
+#, c-format
+msgid "Stream successfully created\n"
+msgstr "Fluxo criado com sucesso\n"
+
+#: ../src/utils/paplay.c:144
+#, c-format
+msgid "Stream errror: %s\n"
+msgstr "Erro de fluxo: %s\n"
+
+#: ../src/utils/paplay.c:165
+#, c-format
+msgid "Connection established.\n"
+msgstr "Conexão estabelecida.\n"
+
+#: ../src/utils/paplay.c:198
+#, c-format
+msgid ""
+"%s [options] [FILE]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -v, --verbose Enable verbose operation\n"
+"\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"
+" --channel-map=CHANNELMAP Set the channel map to the use\n"
+msgstr ""
+"%s [options] [FILE]\n"
+"\n"
+" -h, --help Mostra essa ajuda\n"
+" --version Mostra a versão\n"
+"\n"
+" -v, --verbose Habilida a operação detalhada\n"
+"\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"
+" --stream-name=NAME Como chamar este fluxo no servidor\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
+#, c-format
+msgid ""
+"paplay %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"paplay %s\n"
+"Compilado com libpulse %s\n"
+"Linkado com libpulse %s\n"
+
+#: ../src/utils/paplay.c:292
+#, c-format
+msgid "Invalid channel map\n"
+msgstr "Mapa de canais inválido\n"
+
+#: ../src/utils/paplay.c:314
+#, c-format
+msgid "Failed to open file '%s'\n"
+msgstr "Falha ao abrir o arquivo '%s'\n"
+
+#: ../src/utils/paplay.c:350
+#, c-format
+msgid "Channel map doesn't match file.\n"
+msgstr "O mapa dos canais não coincide com o arquivo.\n"
+
+#: ../src/utils/paplay.c:376
+#, c-format
+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
+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
new file mode 100644
index 00000000..772e1552
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,1836 @@
+# Swedish translation for pulseaudio.
+# Copyright (C) 2008 Free Software Foundation, Inc.
+# This file is distributed under the same license as the pulseaudio package.
+# Daniel Nylander <po@danielnylander.se>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pulseaudio\n"
+"Report-Msgid-Bugs-To: \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"
+"MIME-Version: 1.0\n"
+"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
+msgid "Failed to add bind-now-loader."
+msgstr ""
+
+#: ../src/daemon/ltdl-bind-now.c:184
+msgid "Failed to find original dlopen loader."
+msgstr ""
+
+#: ../src/daemon/polkit.c:55
+#, c-format
+msgid "Cannot connect to system bus: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:65
+#, c-format
+msgid "Cannot get caller from PID: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:77
+msgid "Cannot set UID on caller object."
+msgstr ""
+
+#: ../src/daemon/polkit.c:82
+msgid "Failed to get CK session."
+msgstr ""
+
+#: ../src/daemon/polkit.c:90
+msgid "Cannot set UID on session object."
+msgstr ""
+
+#: ../src/daemon/polkit.c:95
+msgid "Cannot allocate PolKitAction."
+msgstr ""
+
+#: ../src/daemon/polkit.c:100
+msgid "Cannot set action_id"
+msgstr ""
+
+#: ../src/daemon/polkit.c:105
+msgid "Cannot allocate PolKitContext."
+msgstr ""
+
+#: ../src/daemon/polkit.c:110
+#, c-format
+msgid "Cannot initialize PolKitContext: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:119
+#, c-format
+msgid "Could not determine whether caller is authorized: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:139
+#, c-format
+msgid "Cannot obtain auth: %s"
+msgstr ""
+
+#: ../src/daemon/polkit.c:148
+#, c-format
+msgid "PolicyKit responded with '%s'"
+msgstr "PolicyKit svarade med \"%s\""
+
+#: ../src/daemon/main.c:134
+#, c-format
+msgid "Got signal %s."
+msgstr "Fick signal %s."
+
+#: ../src/daemon/main.c:161
+msgid "Exiting."
+msgstr "Avslutar."
+
+#: ../src/daemon/main.c:179
+#, c-format
+msgid "Failed to find user '%s'."
+msgstr "Misslyckades med att hitta användaren \"%s\"."
+
+#: ../src/daemon/main.c:184
+#, c-format
+msgid "Failed to find group '%s'."
+msgstr "Misslyckades med att hitta gruppen \"%s\"."
+
+#: ../src/daemon/main.c:188
+#, c-format
+msgid "Found user '%s' (UID %lu) and group '%s' (GID %lu)."
+msgstr ""
+
+#: ../src/daemon/main.c:193
+#, c-format
+msgid "GID of user '%s' and of group '%s' don't match."
+msgstr ""
+
+#: ../src/daemon/main.c:198
+#, c-format
+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
+#, c-format
+msgid "Failed to create '%s': %s"
+msgstr "Misslyckades med att skapa \"%s\": %s"
+
+#: ../src/daemon/main.c:213
+#, c-format
+msgid "Failed to change group list: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:229
+#, c-format
+msgid "Failed to change GID: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:245
+#, c-format
+msgid "Failed to change UID: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:259
+msgid "Successfully dropped root privileges."
+msgstr ""
+
+#: ../src/daemon/main.c:267
+msgid "System wide mode unsupported on this platform."
+msgstr ""
+
+#: ../src/daemon/main.c:285
+#, c-format
+msgid "setrlimit(%s, (%u, %u)) failed: %s"
+msgstr "setrlimit(%s, (%u, %u)) misslyckades: %s"
+
+#: ../src/daemon/main.c:425
+msgid "Failed to parse command line."
+msgstr ""
+
+#: ../src/daemon/main.c:441
+#, c-format
+msgid "We're in the group '%s', allowing high-priority scheduling."
+msgstr ""
+
+#: ../src/daemon/main.c:448
+#, c-format
+msgid "We're in the group '%s', allowing real-time scheduling."
+msgstr ""
+
+#: ../src/daemon/main.c:456
+msgid "PolicyKit grants us acquire-high-priority privilege."
+msgstr ""
+
+#: ../src/daemon/main.c:459
+msgid "PolicyKit refuses acquire-high-priority privilege."
+msgstr ""
+
+#: ../src/daemon/main.c:464
+msgid "PolicyKit grants us acquire-real-time privilege."
+msgstr ""
+
+#: ../src/daemon/main.c:467
+msgid "PolicyKit refuses acquire-real-time privilege."
+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"
+"We are not in group '"
+msgstr ""
+
+#: ../src/daemon/main.c:497
+msgid ""
+"High-priority scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+
+#: ../src/daemon/main.c:522
+msgid "Successfully increased RLIMIT_RTPRIO"
+msgstr ""
+
+#: ../src/daemon/main.c:525
+#, c-format
+msgid "RLIMIT_RTPRIO failed: %s"
+msgstr "RLIMIT_RTPRIO misslyckades: %s"
+
+#: ../src/daemon/main.c:532
+msgid "Giving up CAP_NICE"
+msgstr ""
+
+#: ../src/daemon/main.c:539
+msgid ""
+"Real-time scheduling enabled in configuration but not allowed by policy."
+msgstr ""
+
+#: ../src/daemon/main.c:597
+msgid "Daemon not running"
+msgstr ""
+
+#: ../src/daemon/main.c:599
+#, c-format
+msgid "Daemon running as PID %u"
+msgstr ""
+
+#: ../src/daemon/main.c:609
+#, c-format
+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)."
+
+#: ../src/daemon/main.c:629
+msgid "Root priviliges required."
+msgstr "Root-behörighet krävs."
+
+#: ../src/daemon/main.c:634
+msgid "--start not supported for system instances."
+msgstr "--start stöds inte för systeminstanser."
+
+#: ../src/daemon/main.c:639
+msgid "Running in system mode, but --disallow-exit not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:642
+msgid "Running in system mode, but --disallow-module-loading not set!"
+msgstr ""
+
+#: ../src/daemon/main.c:645
+msgid "Running in system mode, forcibly disabling SHM mode!"
+msgstr ""
+
+#: ../src/daemon/main.c:650
+msgid "Running in system mode, forcibly disabling exit idle time!"
+msgstr ""
+
+#: ../src/daemon/main.c:677
+msgid "Failed to acquire stdio."
+msgstr ""
+
+#: ../src/daemon/main.c:683
+#, c-format
+msgid "pipe failed: %s"
+msgstr "pipe misslyckades: %s"
+
+#: ../src/daemon/main.c:688
+#, c-format
+msgid "fork() failed: %s"
+msgstr "fork() misslyckades: %s"
+
+#: ../src/daemon/main.c:702
+#, c-format
+msgid "read() failed: %s"
+msgstr "read() misslyckades: %s"
+
+#: ../src/daemon/main.c:708
+msgid "Daemon startup failed."
+msgstr ""
+
+#: ../src/daemon/main.c:710
+msgid "Daemon startup successful."
+msgstr ""
+
+#: ../src/daemon/main.c:780
+#, c-format
+msgid "This is PulseAudio %s"
+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: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: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:808
+#, c-format
+msgid "Machine ID is %s."
+msgstr ""
+
+#: ../src/daemon/main.c:813
+#, c-format
+msgid "Using runtime directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:818
+#, c-format
+msgid "Using state directory %s."
+msgstr ""
+
+#: ../src/daemon/main.c:821
+#, c-format
+msgid "Running in system mode: %s"
+msgstr ""
+
+#: ../src/daemon/main.c:836
+msgid "pa_pid_file_create() failed."
+msgstr "pa_pid_file_create() misslyckades."
+
+#: ../src/daemon/main.c:848
+msgid "Fresh high-resolution timers available! Bon appetit!"
+msgstr ""
+
+#: ../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:860
+msgid "pa_core_new() failed."
+msgstr "pa_core_new() misslyckades."
+
+#: ../src/daemon/main.c:921
+msgid "Failed to initialize daemon."
+msgstr ""
+
+#: ../src/daemon/main.c:926
+msgid "Daemon startup without any loaded modules, refusing to work."
+msgstr ""
+
+#: ../src/daemon/main.c:931
+#, c-format
+msgid "Default sink name (%s) does not exist in name register."
+msgstr ""
+
+#: ../src/daemon/main.c:944
+msgid "Daemon startup complete."
+msgstr ""
+
+#: ../src/daemon/main.c:950
+msgid "Daemon shutdown initiated."
+msgstr ""
+
+#: ../src/daemon/main.c:971
+msgid "Daemon terminated."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:117
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+"COMMANDS:\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+" --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"
+" -k --kill Kill a running daemon\n"
+" --check Check for a running daemon\n"
+"\n"
+"OPTIONS:\n"
+" --system[=BOOL] Run as system-wide instance\n"
+" -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"
+" with elevated RLIMIT_NICE)\n"
+" --realtime[=BOOL] Try to enable realtime scheduling\n"
+" (only available as root, when SUID "
+"or\n"
+" with elevated RLIMIT_RTPRIO)\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"
+" time passed\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"
+" 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"
+" objects (plugins)\n"
+" --resample-method=METHOD Use the specified resampling method\n"
+" (See --dump-resample-methods for\n"
+" possible values)\n"
+" --use-pid-file[=BOOL] Create a PID file\n"
+" --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n"
+" platforms that support it.\n"
+" --disable-shm[=BOOL] Disable shared memory support.\n"
+"\n"
+"STARTUP SCRIPT:\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"
+" after startup\n"
+"\n"
+" -n Don't load default script file\n"
+msgstr ""
+
+#: ../src/daemon/cmdline.c:245
+msgid "--daemonize expects boolean argument"
+msgstr "--daemonize förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:252
+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)."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:274
+msgid "--high-priority expects boolean argument"
+msgstr "--high-priority förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:281
+msgid "--realtime expects boolean argument"
+msgstr "--realtime förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:288
+msgid "--disallow-module-loading expects boolean argument"
+msgstr "--disallow-module-loading förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:295
+msgid "--disallow-exit boolean argument"
+msgstr "--disallow-exit booleskt argument"
+
+#: ../src/daemon/cmdline.c:302
+msgid "--use-pid-file expects boolean argument"
+msgstr "--use-pid-file förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:319
+msgid "Invalid log target: use either 'syslog', 'stderr' or 'auto'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:338
+#, c-format
+msgid "Invalid resample method '%s'."
+msgstr ""
+
+#: ../src/daemon/cmdline.c:345
+msgid "--system expects boolean argument"
+msgstr "--system förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:352
+msgid "--no-cpu-limit expects boolean argument"
+msgstr "--no-cpu-limit förväntar sig ett booleskt argument"
+
+#: ../src/daemon/cmdline.c:359
+msgid "--disable-shm expects boolean argument"
+msgstr "--disable-shm förväntar sig ett booleskt argument"
+
+#: ../src/daemon/dumpmodules.c:60
+#, c-format
+msgid "Name: %s\n"
+msgstr "Namn: %s\n"
+
+#: ../src/daemon/dumpmodules.c:63
+#, c-format
+msgid "No module information available\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:66
+#, c-format
+msgid "Version: %s\n"
+msgstr "Version: %s\n"
+
+#: ../src/daemon/dumpmodules.c:68
+#, c-format
+msgid "Description: %s\n"
+msgstr "Beskrivning: %s\n"
+
+#: ../src/daemon/dumpmodules.c:70
+#, c-format
+msgid "Author: %s\n"
+msgstr "Upphovsman: %s\n"
+
+#: ../src/daemon/dumpmodules.c:72
+#, c-format
+msgid "Usage: %s\n"
+msgstr "Användning: %s\n"
+
+#: ../src/daemon/dumpmodules.c:73
+#, c-format
+msgid "Load Once: %s\n"
+msgstr ""
+
+#: ../src/daemon/dumpmodules.c:77
+#, c-format
+msgid "Path: %s\n"
+msgstr "Sökväg: %s\n"
+
+#: ../src/daemon/daemon-conf.c:205
+#, c-format
+msgid "[%s:%u] Invalid log target '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:221
+#, c-format
+msgid "[%s:%u] Invalid log level '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:237
+#, c-format
+msgid "[%s:%u] Invalid resample method '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:260
+#, c-format
+msgid "[%s:%u] Invalid rlimit '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:267
+#, c-format
+msgid "[%s:%u] rlimit not supported on this platform."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:283
+#, c-format
+msgid "[%s:%u] Invalid sample format '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:301
+#, c-format
+msgid "[%s:%u] Invalid sample rate '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:319
+#, c-format
+msgid "[%s:%u] Invalid sample channels '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:337
+#, c-format
+msgid "[%s:%u] Invalid number of fragments '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:355
+#, c-format
+msgid "[%s:%u] Invalid fragment size '%s'."
+msgstr ""
+
+#: ../src/daemon/daemon-conf.c:373
+#, c-format
+msgid "[%s:%u] Invalid nice level '%s'."
+msgstr ""
+
+#: ../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:644
+#, c-format
+msgid "### Read from configuration file: %s ###\n"
+msgstr ""
+
+#: ../src/daemon/caps.c:63
+msgid "Dropping root priviliges."
+msgstr "Släpper root-behörighet."
+
+#: ../src/daemon/caps.c:103
+msgid "Limited capabilities successfully to CAP_SYS_NICE."
+msgstr ""
+
+#: ../src/pulse/channelmap.c:102
+msgid "Mono"
+msgstr "Mono"
+
+#: ../src/pulse/channelmap.c:104
+msgid "Front Center"
+msgstr "Center fram"
+
+#: ../src/pulse/channelmap.c:105
+msgid "Front Left"
+msgstr "Vänster fram"
+
+#: ../src/pulse/channelmap.c:106
+msgid "Front Right"
+msgstr "Höger fram"
+
+#: ../src/pulse/channelmap.c:108
+msgid "Rear Center"
+msgstr "Center bak"
+
+#: ../src/pulse/channelmap.c:109
+msgid "Rear Left"
+msgstr "Vänster bak"
+
+#: ../src/pulse/channelmap.c:110
+msgid "Rear Right"
+msgstr "Höger bak"
+
+#: ../src/pulse/channelmap.c:112
+msgid "Low Frequency Emmiter"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:114
+msgid "Front Left-of-center"
+msgstr "Vänster-om-center fram"
+
+#: ../src/pulse/channelmap.c:115
+msgid "Front Right-of-center"
+msgstr "Höger-om-center fram"
+
+#: ../src/pulse/channelmap.c:117
+msgid "Side Left"
+msgstr "Vänster sida"
+
+#: ../src/pulse/channelmap.c:118
+msgid "Side Right"
+msgstr "Höger sida"
+
+#: ../src/pulse/channelmap.c:120
+msgid "Auxiliary 0"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:121
+msgid "Auxiliary 1"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:122
+msgid "Auxiliary 2"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:123
+msgid "Auxiliary 3"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:124
+msgid "Auxiliary 4"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:125
+msgid "Auxiliary 5"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:126
+msgid "Auxiliary 6"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:127
+msgid "Auxiliary 7"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:128
+msgid "Auxiliary 8"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:129
+msgid "Auxiliary 9"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:130
+msgid "Auxiliary 10"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:131
+msgid "Auxiliary 11"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:132
+msgid "Auxiliary 12"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:133
+msgid "Auxiliary 13"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:134
+msgid "Auxiliary 14"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:135
+msgid "Auxiliary 15"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:136
+msgid "Auxiliary 16"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:137
+msgid "Auxiliary 17"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:138
+msgid "Auxiliary 18"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:139
+msgid "Auxiliary 19"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:140
+msgid "Auxiliary 20"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:141
+msgid "Auxiliary 21"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:142
+msgid "Auxiliary 22"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:143
+msgid "Auxiliary 23"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:144
+msgid "Auxiliary 24"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:145
+msgid "Auxiliary 25"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:146
+msgid "Auxiliary 26"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:147
+msgid "Auxiliary 27"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:148
+msgid "Auxiliary 28"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:149
+msgid "Auxiliary 29"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:150
+msgid "Auxiliary 30"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:151
+msgid "Auxiliary 31"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:153
+msgid "Top Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:155
+msgid "Top Front Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:156
+msgid "Top Front Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:157
+msgid "Top Front Right"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:159
+msgid "Top Rear Center"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:160
+msgid "Top Rear Left"
+msgstr ""
+
+#: ../src/pulse/channelmap.c:161
+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"
+
+#: ../src/pulse/error.c:44
+msgid "Access denied"
+msgstr "Åtkomst nekad"
+
+#: ../src/pulse/error.c:45
+msgid "Unknown command"
+msgstr "Okänt kommando"
+
+#: ../src/pulse/error.c:46
+msgid "Invalid argument"
+msgstr "Ogiltigt argument"
+
+#: ../src/pulse/error.c:47
+msgid "Entity exists"
+msgstr "Entiteten finns"
+
+#: ../src/pulse/error.c:48
+msgid "No such entity"
+msgstr "Ingen sådan entitet"
+
+#: ../src/pulse/error.c:49
+msgid "Connection refused"
+msgstr "Anslutning nekades"
+
+#: ../src/pulse/error.c:50
+msgid "Protocol error"
+msgstr "Protokollfel"
+
+#: ../src/pulse/error.c:51
+msgid "Timeout"
+msgstr "Tidsgräns nåddes"
+
+#: ../src/pulse/error.c:52
+msgid "No authorization key"
+msgstr ""
+
+#: ../src/pulse/error.c:53
+msgid "Internal error"
+msgstr "Internt fel"
+
+#: ../src/pulse/error.c:54
+msgid "Connection terminated"
+msgstr "Anslutningen terminerad"
+
+#: ../src/pulse/error.c:55
+msgid "Entity killed"
+msgstr ""
+
+#: ../src/pulse/error.c:56
+msgid "Invalid server"
+msgstr "Ogiltig server"
+
+#: ../src/pulse/error.c:57
+msgid "Module initalization failed"
+msgstr ""
+
+#: ../src/pulse/error.c:58
+msgid "Bad state"
+msgstr "Felaktigt tillstånd"
+
+#: ../src/pulse/error.c:59
+msgid "No data"
+msgstr "Inget data"
+
+#: ../src/pulse/error.c:60
+msgid "Incompatible protocol version"
+msgstr ""
+
+#: ../src/pulse/error.c:61
+msgid "Too large"
+msgstr "För stor"
+
+#: ../src/pulse/error.c:62
+msgid "Not supported"
+msgstr "Stöds inte"
+
+#: ../src/pulse/error.c:63
+msgid "Unknown error code"
+msgstr "Okänd felkod"
+
+#: ../src/pulse/error.c:64
+msgid "No such extension"
+msgstr ""
+
+#: ../src/pulse/client-conf-x11.c:55 ../src/utils/pax11publish.c:100
+msgid "XOpenDisplay() failed"
+msgstr "XOpenDisplay() misslyckades"
+
+#: ../src/pulse/client-conf-x11.c:78
+msgid "Failed to parse cookie data"
+msgstr ""
+
+#: ../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:516
+msgid "No cookie loaded. Attempting to connect without."
+msgstr ""
+
+#: ../src/pulse/context.c:642
+#, c-format
+msgid "fork(): %s"
+msgstr "fork(): %s"
+
+#: ../src/pulse/context.c:695
+#, c-format
+msgid "waitpid(): %s"
+msgstr "waitpid(): %s"
+
+#: ../src/pulse/context.c:1256
+#, c-format
+msgid "Received message for unknown extension '%s'"
+msgstr ""
+
+#: ../src/utils/pacat.c:93
+#, c-format
+msgid "pa_stream_write() failed: %s\n"
+msgstr "pa_stream_write() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:132
+#, c-format
+msgid "pa_stream_peek() failed: %s\n"
+msgstr "pa_stream_peek() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:141
+#, c-format
+msgid "Buffer overrun, dropping incoming data\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:143
+#, c-format
+msgid "pa_stream_drop() failed: %s\n"
+msgstr "pa_stream_drop() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:169
+#, c-format
+msgid "Stream successfully created.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:172
+#, c-format
+msgid "pa_stream_get_buffer_attr() failed: %s\n"
+msgstr "pa_stream_get_buffer_attr() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:176
+#, c-format
+msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:179
+#, c-format
+msgid "Buffer metrics: maxlength=%u, fragsize=%u\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:183
+#, c-format
+msgid "Using sample spec '%s', channel map '%s'.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:187
+#, c-format
+msgid "Connected to device %s (%u, %ssuspended).\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:197
+#, c-format
+msgid "Stream error: %s\n"
+msgstr "Strömfel: %s\n"
+
+#: ../src/utils/pacat.c:207
+#, c-format
+msgid "Stream device suspended.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:209
+#, c-format
+msgid "Stream device resumed.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:217
+#, c-format
+msgid "Stream underrun.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:224
+#, c-format
+msgid "Stream overrun.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:231
+#, c-format
+msgid "Stream started.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:238
+#, c-format
+msgid "Stream moved to device %s (%u, %ssuspended).%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:238
+msgid "not "
+msgstr "inte "
+
+#: ../src/utils/pacat.c:259
+#, c-format
+msgid "Connection established.%s \n"
+msgstr ""
+
+#: ../src/utils/pacat.c:262
+#, c-format
+msgid "pa_stream_new() failed: %s\n"
+msgstr "pa_stream_new() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:287
+#, c-format
+msgid "pa_stream_connect_playback() failed: %s\n"
+msgstr "pa_stream_connect_playback() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:293
+#, c-format
+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
+#, c-format
+msgid "Connection failure: %s\n"
+msgstr "Anslutningsfel: %s\n"
+
+#: ../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
+#, c-format
+msgid "Playback stream drained.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:343 ../src/utils/paplay.c:92
+#, c-format
+msgid "Draining connection to server.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:369
+#, c-format
+msgid "Got EOF.\n"
+msgstr "Fick filslut.\n"
+
+#: ../src/utils/pacat.c:375
+#, c-format
+msgid "pa_stream_drain(): %s\n"
+msgstr "pa_stream_drain(): %s\n"
+
+#: ../src/utils/pacat.c:385
+#, c-format
+msgid "read() failed: %s\n"
+msgstr "read() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:417
+#, c-format
+msgid "write() failed: %s\n"
+msgstr "write() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:438
+#, c-format
+msgid "Got signal, exiting.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:452
+#, c-format
+msgid "Failed to get latency: %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:457
+#, c-format
+msgid "Time: %0.3f sec; Latency: %0.0f usec. \r"
+msgstr "Tid: %0.3f sec; Latens: %0.0f ms \r"
+
+#: ../src/utils/pacat.c:477
+#, c-format
+msgid "pa_stream_update_timing_info() failed: %s\n"
+msgstr "pa_stream_update_timing_info() misslyckades: %s\n"
+
+#: ../src/utils/pacat.c:490
+#, c-format
+msgid ""
+"%s [options]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -r, --record Create a connection for recording\n"
+" -p, --playback Create a connection for playback\n"
+"\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"
+" (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"
+" being connected to.\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"
+" --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"
+msgstr ""
+
+#: ../src/utils/pacat.c:591
+#, c-format
+msgid ""
+"pacat %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:647
+#, c-format
+msgid "Invalid channel map '%s'\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:676
+#, c-format
+msgid "Invalid latency specification '%s'\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:683
+#, c-format
+msgid "Invalid process time specification '%s'\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:694
+#, c-format
+msgid "Invalid sample specification\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:699
+#, c-format
+msgid "Channel map doesn't match sample specification\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:706
+#, c-format
+msgid "Opening a %s stream with sample specification '%s'.\n"
+msgstr ""
+
+#: ../src/utils/pacat.c:706
+msgid "recording"
+msgstr ""
+
+#: ../src/utils/pacat.c:706
+msgid "playback"
+msgstr ""
+
+#: ../src/utils/pacat.c:714
+#, c-format
+msgid "open(): %s\n"
+msgstr "open(): %s\n"
+
+#: ../src/utils/pacat.c:719
+#, c-format
+msgid "dup2(): %s\n"
+msgstr "dup2(): %s\n"
+
+#: ../src/utils/pacat.c:729
+#, c-format
+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
+#, c-format
+msgid "pa_mainloop_new() failed.\n"
+msgstr "pa_mainloop_new() misslyckades.\n"
+
+#: ../src/utils/pacat.c:763
+#, c-format
+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
+#, c-format
+msgid "pa_context_new() failed.\n"
+msgstr "pa_context_new() misslyckades.\n"
+
+#: ../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: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"
+
+#: ../src/utils/pasuspender.c:81
+#, c-format
+msgid "fork(): %s\n"
+msgstr "fork(): %s\n"
+
+#: ../src/utils/pasuspender.c:92
+#, c-format
+msgid "execvp(): %s\n"
+msgstr "execvp(): %s\n"
+
+#: ../src/utils/pasuspender.c:109
+#, c-format
+msgid "Failure to suspend: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:124
+#, c-format
+msgid "Failure to resume: %s\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:147
+#, c-format
+msgid "WARNING: Sound server is not local, not suspending.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:176 ../src/utils/pactl.c:672
+#: ../src/utils/paplay.c:191
+#, c-format
+msgid "Got SIGINT, exiting.\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:194
+#, c-format
+msgid "WARNING: Child process terminated by signal %u\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:212
+#, c-format
+msgid ""
+"%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"
+"\n"
+msgstr ""
+
+#: ../src/utils/pasuspender.c:251
+#, c-format
+msgid ""
+"pasuspender %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pasuspender %s\n"
+"Kompilerad med libpulse %s\n"
+"Länkad med libpulse %s\n"
+
+#: ../src/utils/pactl.c:107
+#, c-format
+msgid "Failed to get statistics: %s\n"
+msgstr "Misslyckades med att få statistik: %s\n"
+
+#: ../src/utils/pactl.c:113
+#, c-format
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:116
+#, c-format
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:119
+#, c-format
+msgid "Sample cache size: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:128
+#, c-format
+msgid "Failed to get server information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:135
+#, c-format
+msgid ""
+"User name: %s\n"
+"Host Name: %s\n"
+"Server Name: %s\n"
+"Server Version: %s\n"
+"Default Sample Specification: %s\n"
+"Default Sink: %s\n"
+"Default Source: %s\n"
+"Cookie: %08x\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:160
+#, c-format
+msgid "Failed to get sink information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:176
+#, c-format
+msgid ""
+"*** Sink #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor Source: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:193 ../src/utils/pactl.c:371
+msgid "muted"
+msgstr "tystad"
+
+#: ../src/utils/pactl.c:212
+#, c-format
+msgid "Failed to get source information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:228
+#, c-format
+msgid ""
+"*** Source #%u ***\n"
+"Name: %s\n"
+"Driver: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Owner Module: %u\n"
+"Volume: %s\n"
+"Monitor of Sink: %s\n"
+"Latency: %0.0f usec, configured %0.0f usec\n"
+"Flags: %s%s%s%s%s%s\n"
+"Properties:\n"
+"%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
+msgid "n/a"
+msgstr ""
+
+#: ../src/utils/pactl.c:263
+#, c-format
+msgid "Failed to get module information: %s\n"
+msgstr "Misslyckades med att få modulinformation: %s\n"
+
+#: ../src/utils/pactl.c:281
+#, c-format
+msgid ""
+"*** Module #%u ***\n"
+"Name: %s\n"
+"Argument: %s\n"
+"Usage counter: %s\n"
+"Auto unload: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:298
+#, c-format
+msgid "Failed to get client information: %s\n"
+msgstr "Misslyckades med att få klientinformation: %s\n"
+
+#: ../src/utils/pactl.c:316
+#, c-format
+msgid ""
+"*** Client #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:333
+#, c-format
+msgid "Failed to get sink input information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:352
+#, c-format
+msgid ""
+"*** Sink Input #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Sink: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Volume: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Sink Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:385
+#, c-format
+msgid "Failed to get source output information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:405
+#, c-format
+msgid ""
+"*** Source Output #%u ***\n"
+"Driver: %s\n"
+"Owner Module: %s\n"
+"Client: %s\n"
+"Source: %u\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Buffer Latency: %0.0f usec\n"
+"Source Latency: %0.0f usec\n"
+"Resample method: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:436
+#, c-format
+msgid "Failed to get sample information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:455
+#, c-format
+msgid ""
+"*** Sample #%u ***\n"
+"Name: %s\n"
+"Volume: %s\n"
+"Sample Specification: %s\n"
+"Channel Map: %s\n"
+"Duration: %0.1fs\n"
+"Size: %s\n"
+"Lazy: %s\n"
+"Filename: %s\n"
+"Properties:\n"
+"%s"
+msgstr ""
+
+#: ../src/utils/pactl.c:481
+#, c-format
+msgid "Failed to get autoload information: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:497
+#, c-format
+msgid ""
+"*** Autoload Entry #%u ***\n"
+"Name: %s\n"
+"Type: %s\n"
+"Module: %s\n"
+"Argument: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:504
+msgid "sink"
+msgstr "sink"
+
+#: ../src/utils/pactl.c:504
+msgid "source"
+msgstr "källa"
+
+#: ../src/utils/pactl.c:511 ../src/utils/pactl.c:521
+#, c-format
+msgid "Failure: %s\n"
+msgstr "Fel: %s\n"
+
+#: ../src/utils/pactl.c:545
+#, c-format
+msgid "Failed to upload sample: %s\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:562
+#, c-format
+msgid "Premature end of file\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:678
+#, c-format
+msgid ""
+"%s [options] stat\n"
+"%s [options] list\n"
+"%s [options] exit\n"
+"%s [options] upload-sample FILENAME [NAME]\n"
+"%s [options] play-sample NAME [SINK]\n"
+"%s [options] remove-sample NAME\n"
+"%s [options] move-sink-input ID SINK\n"
+"%s [options] move-source-output ID SOURCE\n"
+"%s [options] load-module NAME [ARGS ...]\n"
+"%s [options] unload-module ID\n"
+"%s [options] suspend-sink [SINK] 1|0\n"
+"%s [options] suspend-source [SOURCE] 1|0\n"
+"\n"
+" -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"
+msgstr ""
+
+#: ../src/utils/pactl.c:729
+#, c-format
+msgid ""
+"pactl %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"pactl %s\n"
+"Kompilerad med libpulse %s\n"
+"Länkad med libpulse %s\n"
+
+#: ../src/utils/pactl.c:768
+#, c-format
+msgid "Please specify a sample file to load\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:790
+#, c-format
+msgid "Failed to open sound file.\n"
+msgstr "Misslyckades med att öppna ljudfil.\n"
+
+#: ../src/utils/pactl.c:802
+#, c-format
+msgid "You have to specify a sample name to play\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:814
+#, c-format
+msgid "You have to specify a sample name to remove\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:822
+#, c-format
+msgid "You have to specify a sink input index and a sink\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:831
+#, c-format
+msgid "You have to specify a source output index and a source\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:845
+#, c-format
+msgid "You have to specify a module name and arguments.\n"
+msgstr ""
+
+#: ../src/utils/pactl.c:865
+#, c-format
+msgid "You have to specify a module index\n"
+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"
+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"
+msgstr ""
+
+#: ../src/utils/pactl.c:904
+#, c-format
+msgid "No valid command specified.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:61
+#, c-format
+msgid ""
+"%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"
+" -r Remove PulseAudio data from X11 display\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:94
+#, c-format
+msgid "Failed to parse command line.\n"
+msgstr "Misslyckades med att tolka kommandorad.\n"
+
+#: ../src/utils/pax11publish.c:108
+#, c-format
+msgid "Server: %s\n"
+msgstr "Server: %s\n"
+
+#: ../src/utils/pax11publish.c:110
+#, c-format
+msgid "Source: %s\n"
+msgstr "Källa: %s\n"
+
+#: ../src/utils/pax11publish.c:112
+#, c-format
+msgid "Sink: %s\n"
+msgstr "Sink: %s\n"
+
+#: ../src/utils/pax11publish.c:114
+#, c-format
+msgid "Cookie: %s\n"
+msgstr "Kaka: %s\n"
+
+#: ../src/utils/pax11publish.c:132
+#, c-format
+msgid "Failed to parse cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:137
+#, c-format
+msgid "Failed to save cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:152
+#, c-format
+msgid "Failed to load client configuration file.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:157
+#, c-format
+msgid "Failed to read environment configuration data.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:174
+#, c-format
+msgid "Failed to get FQDN.\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:194
+#, c-format
+msgid "Failed to load cookie data\n"
+msgstr ""
+
+#: ../src/utils/pax11publish.c:211
+#, c-format
+msgid "Not yet implemented.\n"
+msgstr "Ännu inte implementerad.\n"
+
+#: ../src/utils/pacmd.c:64
+#, c-format
+msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
+msgstr ""
+
+#: ../src/utils/pacmd.c:81
+#, c-format
+msgid "connect(): %s"
+msgstr "connect(): %s"
+
+#: ../src/utils/pacmd.c:89
+msgid "Failed to kill PulseAudio daemon."
+msgstr ""
+
+#: ../src/utils/pacmd.c:97
+msgid "Daemon not responding."
+msgstr ""
+
+#: ../src/utils/pacmd.c:112
+#, c-format
+msgid "select(): %s"
+msgstr "select(): %s"
+
+#: ../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
+#, c-format
+msgid "write(): %s"
+msgstr "write(): %s"
+
+#: ../src/utils/paplay.c:139
+#, c-format
+msgid "Stream successfully created\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:144
+#, c-format
+msgid "Stream errror: %s\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:165
+#, c-format
+msgid "Connection established.\n"
+msgstr "Anslutning etablerad.\n"
+
+#: ../src/utils/paplay.c:198
+#, c-format
+msgid ""
+"%s [options] [FILE]\n"
+"\n"
+" -h, --help Show this help\n"
+" --version Show version\n"
+"\n"
+" -v, --verbose Enable verbose operation\n"
+"\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"
+" --channel-map=CHANNELMAP Set the channel map to the use\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:255
+#, c-format
+msgid ""
+"paplay %s\n"
+"Compiled with libpulse %s\n"
+"Linked with libpulse %s\n"
+msgstr ""
+"paplay %s\n"
+"Kompilerad med libpulse %s\n"
+"Länkad med libpulse %s\n"
+
+#: ../src/utils/paplay.c:292
+#, c-format
+msgid "Invalid channel map\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:314
+#, c-format
+msgid "Failed to open file '%s'\n"
+msgstr "Misslyckades med att öppna filen \"%s\"\n"
+
+#: ../src/utils/paplay.c:350
+#, c-format
+msgid "Channel map doesn't match file.\n"
+msgstr ""
+
+#: ../src/utils/paplay.c:376
+#, c-format
+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 6902eb9f..72c38cc6 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -1,3 +1,5 @@
+prioq-test
+lock-autospawn-test
*.lo
*.o
*.la
@@ -7,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 29a6ef47..b9d00831 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -45,28 +45,31 @@ 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 += $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS
-AM_CFLAGS += $(LTDLINCL)
-AM_CFLAGS += $(LIBSAMPLERATE_CFLAGS) $(LIBSNDFILE_CFLAGS) $(LIBSPEEX_CFLAGS)
-AM_CFLAGS += -DPA_DLSEARCHPATH=\"$(modlibexecdir)\"
-AM_CFLAGS += -DPA_DEFAULT_CONFIG_DIR=\"$(PA_DEFAULT_CONFIG_DIR)\"
-AM_CFLAGS += -DPA_BINARY=\"$(PA_BINARY)\"
-AM_CFLAGS += -DPA_SYSTEM_RUNTIME_PATH=\"$(PA_SYSTEM_RUNTIME_PATH)\"
-AM_CFLAGS += -DPA_SYSTEM_CONFIG_PATH=\"$(PA_SYSTEM_CONFIG_PATH)\"
-AM_CFLAGS += -DPA_SYSTEM_STATE_PATH=\"$(PA_SYSTEM_STATE_PATH)\"
-AM_CFLAGS += -DAO_REQUIRE_CAS
-AM_CFLAGS += -DPULSE_LOCALEDIR=\"$(pulselocaledir)\"
-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)
-
-# Only required on some platforms but defined for all to avoid errors
-AM_LDFLAGS = -Wl,-no-undefined -Wl,--gc-sections
+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 \
+ -I$(top_builddir)/src/modules/raop \
+ $(PTHREAD_CFLAGS) -D_POSIX_PTHREAD_SEMANTICS \
+ $(LTDLINCL) \
+ $(LIBSAMPLERATE_CFLAGS) \
+ $(LIBSNDFILE_CFLAGS) \
+ $(LIBSPEEX_CFLAGS) \
+ -DPA_DLSEARCHPATH=\"$(modlibexecdir)\" \
+ -DPA_DEFAULT_CONFIG_DIR=\"$(PA_DEFAULT_CONFIG_DIR)\" \
+ -DPA_BINARY=\"$(PA_BINARY)\" \
+ -DPA_SYSTEM_RUNTIME_PATH=\"$(PA_SYSTEM_RUNTIME_PATH)\" \
+ -DPA_SYSTEM_CONFIG_PATH=\"$(PA_SYSTEM_CONFIG_PATH)\" \
+ -DPA_SYSTEM_STATE_PATH=\"$(PA_SYSTEM_STATE_PATH)\" \
+ -DAO_REQUIRE_CAS \
+ -DPULSE_LOCALEDIR=\"$(pulselocaledir)\" \
+ -DPA_MACHINE_ID=\"$(localstatedir)/lib/dbus/machine-id\"
+
+AM_LIBADD = $(PTHREAD_LIBS) $(INTLLIBS)
+AM_LDADD = $(PTHREAD_LIBS) $(INTLLIBS)
+AM_LDFLAGS = -Wl,-z,nodelete
if STATIC_BINS
BINLDFLAGS = -static
@@ -77,18 +80,6 @@ AM_LDFLAGS+=-Wl,--export-all-symbols
WINSOCK_LIBS=-lwsock32 -lws2_32 -lwininet
endif
-if OS_IS_WIN32
-PA_THREAD_OBJS = \
- pulsecore/mutex-win32.c pulsecore/mutex.h \
- pulsecore/thread-win32.c pulsecore/thread.h \
- pulsecore/semaphore-win32.c pulsecore/semaphore.h
-else
-PA_THREAD_OBJS = \
- pulsecore/mutex-posix.c pulsecore/mutex.h \
- pulsecore/thread-posix.c pulsecore/thread.h \
- pulsecore/semaphore-posix.c pulsecore/semaphore.h
-endif
-
###################################
# Extra files #
###################################
@@ -139,10 +130,9 @@ pulseaudio_SOURCES = \
daemon/main.c
pulseaudio_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS) $(LIBSAMPLERATE_CFLAGS) $(LIBSPEEX_CFLAGS) $(LIBSNDFILE_CFLAGS) $(CAP_CFLAGS) $(LIBOIL_CFLAGS) $(DBUS_CFLAGS)
-pulseaudio_CPPFLAGS = $(AM_CPPFLAGS)
-pulseaudio_LDADD = $(AM_LDADD) libpulsecore.la $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSPEEX_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) $(LIBOIL_LIBS) $(DBUS_LIBS)
+pulseaudio_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSPEEX_LIBS) $(LIBSNDFILE_LIBS) $(CAP_LIBS) $(LIBOIL_LIBS) $(DBUS_LIBS)
# This is needed because automake doesn't properly expand the foreach below
-pulseaudio_DEPENDENCIES = libpulsecore.la $(PREOPEN_LIBS)
+pulseaudio_DEPENDENCIES = libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la $(PREOPEN_LIBS)
if PREOPEN_MODS
PREOPEN_LIBS = $(PREOPEN_MODS)
@@ -157,14 +147,11 @@ pulseaudio_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) -dlopen force $(foreach f,$(PRE
endif
if HAVE_POLKIT
-
policy_DATA = daemon/org.pulseaudio.policy
pulseaudio_SOURCES += daemon/polkit.c daemon/polkit.h
pulseaudio_CFLAGS += $(POLKIT_CFLAGS)
pulseaudio_LDADD += $(POLKIT_LIBS)
-
-
endif
###################################
@@ -201,24 +188,24 @@ paplay_LDADD = $(AM_LDADD) libpulse.la $(LIBSNDFILE_LIBS)
paplay_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
paplay_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-pactl_SOURCES = utils/pactl.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)
-pactl_LDADD = $(AM_LDADD) libpulse.la $(LIBSNDFILE_LIBS)
+pactl_SOURCES = utils/pactl.c
+pactl_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(LIBSNDFILE_LIBS)
pactl_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
pactl_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-pasuspender_SOURCES = utils/pasuspender.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)
-pasuspender_LDADD = $(AM_LDADD) libpulse.la $(LIBSNDFILE_LIBS)
+pasuspender_SOURCES = utils/pasuspender.c
+pasuspender_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(LIBSNDFILE_LIBS)
pasuspender_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
pasuspender_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-pacmd_SOURCES = utils/pacmd.c pulsecore/pid.c pulsecore/pid.h 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)
+pacmd_SOURCES = utils/pacmd.c
pacmd_CFLAGS = $(AM_CFLAGS)
-pacmd_LDADD = $(AM_LDADD) libpulse.la
+pacmd_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
pacmd_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-pax11publish_SOURCES = utils/pax11publish.c pulsecore/x11prop.c pulsecore/x11prop.h pulse/client-conf.c pulse/client-conf.h pulsecore/authkey.h pulsecore/authkey.c pulsecore/random.h pulsecore/random.c pulsecore/conf-parser.c pulsecore/conf-parser.h 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)
+pax11publish_SOURCES = utils/pax11publish.c
pax11publish_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
-pax11publish_LDADD = $(AM_LDADD) libpulse.la $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS)
+pax11publish_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS)
pax11publish_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
pabrowse_SOURCES = utils/pabrowse.c
@@ -262,7 +249,9 @@ noinst_PROGRAMS = \
envelope-test \
proplist-test \
rtstutter \
- stripnul
+ stripnul \
+ lock-autospawn-test \
+ prioq-test
if HAVE_SIGXCPU
noinst_PROGRAMS += \
@@ -282,12 +271,12 @@ mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
thread_mainloop_test_SOURCES = tests/thread-mainloop-test.c
thread_mainloop_test_CFLAGS = $(AM_CFLAGS)
-thread_mainloop_test_LDADD = $(AM_LDADD) libpulsecore.la libpulse.la
+thread_mainloop_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
thread_mainloop_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
utf8_test_SOURCES = tests/utf8-test.c
utf8_test_CFLAGS = $(AM_CFLAGS)
-utf8_test_LDADD = $(AM_LDADD) libpulsecore.la
+utf8_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
utf8_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
get_binary_name_test_SOURCES = tests/get-binary-name-test.c
@@ -295,56 +284,54 @@ get_binary_name_test_CFLAGS = $(AM_CFLAGS)
get_binary_name_test_LDADD = $(AM_LDADD) libpulse.la
get_binary_name_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
-ipacl_test_SOURCES = tests/ipacl-test.c \
- pulsecore/ipacl.c pulsecore/ipacl.h \
- pulsecore/inet_pton.c pulsecore/inet_pton.h
+ipacl_test_SOURCES = tests/ipacl-test.c
ipacl_test_CFLAGS = $(AM_CFLAGS)
-ipacl_test_LDADD = $(AM_LDADD) libpulsecore.la
+ipacl_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
ipacl_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
hook_list_test_SOURCES = tests/hook-list-test.c
hook_list_test_CFLAGS = $(AM_CFLAGS)
-hook_list_test_LDADD = $(AM_LDADD) libpulsecore.la
+hook_list_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
hook_list_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
memblock_test_SOURCES = tests/memblock-test.c
memblock_test_CFLAGS = $(AM_CFLAGS)
-memblock_test_LDADD = $(AM_LDADD) libpulsecore.la
+memblock_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
memblock_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
thread_test_SOURCES = tests/thread-test.c
thread_test_CFLAGS = $(AM_CFLAGS)
-thread_test_LDADD = $(AM_LDADD) libpulsecore.la
+thread_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
thread_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
flist_test_SOURCES = tests/flist-test.c
flist_test_CFLAGS = $(AM_CFLAGS)
-flist_test_LDADD = $(AM_LDADD) libpulsecore.la
+flist_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
flist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
asyncq_test_SOURCES = tests/asyncq-test.c
asyncq_test_CFLAGS = $(AM_CFLAGS)
-asyncq_test_LDADD = $(AM_LDADD) libpulsecore.la
+asyncq_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
asyncq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
asyncmsgq_test_SOURCES = tests/asyncmsgq-test.c
asyncmsgq_test_CFLAGS = $(AM_CFLAGS)
-asyncmsgq_test_LDADD = $(AM_LDADD) libpulsecore.la
+asyncmsgq_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
asyncmsgq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
queue_test_SOURCES = tests/queue-test.c
queue_test_CFLAGS = $(AM_CFLAGS)
-queue_test_LDADD = $(AM_LDADD) libpulsecore.la
+queue_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
queue_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
rtpoll_test_SOURCES = tests/rtpoll-test.c
rtpoll_test_CFLAGS = $(AM_CFLAGS)
-rtpoll_test_LDADD = $(AM_LDADD) libpulsecore.la
+rtpoll_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
rtpoll_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
mcalign_test_SOURCES = tests/mcalign-test.c
mcalign_test_CFLAGS = $(AM_CFLAGS)
-mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la
+mcalign_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
mcalign_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
pacat_simple_SOURCES = tests/pacat-simple.c
@@ -359,12 +346,12 @@ parec_simple_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
strlist_test_SOURCES = tests/strlist-test.c
strlist_test_CFLAGS = $(AM_CFLAGS)
-strlist_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la libstrlist.la
+strlist_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
strlist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
close_test_SOURCES = tests/close-test.c
close_test_CFLAGS = $(AM_CFLAGS)
-close_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la libstrlist.la
+close_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
close_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
voltest_SOURCES = tests/voltest.c
@@ -379,12 +366,12 @@ channelmap_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
cpulimit_test_SOURCES = tests/cpulimit-test.c daemon/cpulimit.c daemon/cpulimit.h
cpulimit_test_CFLAGS = $(AM_CFLAGS)
-cpulimit_test_LDADD = $(AM_LDADD) libpulsecore.la
+cpulimit_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
cpulimit_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
cpulimit_test2_SOURCES = tests/cpulimit-test.c daemon/cpulimit.c daemon/cpulimit.h
cpulimit_test2_CFLAGS = $(AM_CFLAGS) -DTEST2
-cpulimit_test2_LDADD = $(AM_LDADD) libpulsecore.la
+cpulimit_test2_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
cpulimit_test2_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
mainloop_test_glib_SOURCES = $(mainloop_test_SOURCES)
@@ -394,7 +381,7 @@ mainloop_test_glib_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
memblockq_test_SOURCES = tests/memblockq-test.c
memblockq_test_CFLAGS = $(AM_CFLAGS)
-memblockq_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore.la
+memblockq_test_LDADD = $(AM_LDADD) $(WINSOCK_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
memblockq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
sync_playback_SOURCES = tests/sync-playback.c
@@ -403,55 +390,160 @@ sync_playback_CFLAGS = $(AM_CFLAGS)
sync_playback_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
interpol_test_SOURCES = tests/interpol-test.c
-interpol_test_LDADD = $(AM_LDADD) libpulse.la libpulsecore.la
+interpol_test_LDADD = $(AM_LDADD) libpulse.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
interpol_test_CFLAGS = $(AM_CFLAGS)
interpol_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
sig2str_test_SOURCES = tests/sig2str-test.c
-sig2str_test_LDADD = $(AM_LDADD) libpulsecore.la
+sig2str_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
sig2str_test_CFLAGS = $(AM_CFLAGS)
sig2str_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
resampler_test_SOURCES = tests/resampler-test.c
-resampler_test_LDADD = $(AM_LDADD) libpulsecore.la
+resampler_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
resampler_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
resampler_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
mix_test_SOURCES = tests/mix-test.c
-mix_test_LDADD = $(AM_LDADD) libpulsecore.la
+mix_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
mix_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
mix_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
remix_test_SOURCES = tests/remix-test.c
-remix_test_LDADD = $(AM_LDADD) libpulsecore.la
+remix_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
remix_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
remix_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
smoother_test_SOURCES = tests/smoother-test.c
-smoother_test_LDADD = $(AM_LDADD) libpulsecore.la
+smoother_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
smoother_test_CFLAGS = $(AM_CFLAGS)
smoother_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS)
envelope_test_SOURCES = tests/envelope-test.c
-envelope_test_LDADD = $(AM_LDADD) libpulsecore.la
+envelope_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
envelope_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
envelope_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
proplist_test_SOURCES = tests/proplist-test.c
-proplist_test_LDADD = $(AM_LDADD) libpulsecore.la
+proplist_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
proplist_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
proplist_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
rtstutter_SOURCES = tests/rtstutter.c
-rtstutter_LDADD = $(AM_LDADD) libpulsecore.la
+rtstutter_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
rtstutter_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
rtstutter_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
stripnul_SOURCES = tests/stripnul.c
-stripnul_LDADD = $(AM_LDADD) libpulsecore.la
+stripnul_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
stripnul_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
stripnul_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
+lock_autospawn_test_SOURCES = tests/lock-autospawn-test.c
+lock_autospawn_test_LDADD = $(AM_LDADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.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-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+prioq_test_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
+prioq_test_LDFLAGS = $(AM_LDFLAGS) $(BINLDFLAGS) $(LIBOIL_LIBS)
+
+###################################
+# Common library #
+###################################
+
+lib_LTLIBRARIES = \
+ libpulsecommon-@PA_MAJORMINORMICRO@.la
+
+libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES = \
+ pulse/client-conf.c pulse/client-conf.h \
+ pulse/i18n.c pulse/i18n.h \
+ pulsecore/authkey.c pulsecore/authkey.h \
+ pulsecore/conf-parser.c pulsecore/conf-parser.h \
+ pulsecore/core-error.c pulsecore/core-error.h \
+ pulsecore/core-util.c pulsecore/core-util.h \
+ pulsecore/creds.h \
+ pulsecore/dynarray.c pulsecore/dynarray.h \
+ pulsecore/endianmacros.h \
+ pulsecore/flist.c pulsecore/flist.h \
+ pulsecore/hashmap.c pulsecore/hashmap.h \
+ pulsecore/idxset.c pulsecore/idxset.h \
+ pulsecore/inet_ntop.c pulsecore/inet_ntop.h \
+ pulsecore/inet_pton.c pulsecore/inet_pton.h \
+ pulsecore/iochannel.c pulsecore/iochannel.h \
+ pulsecore/ioline.c pulsecore/ioline.h \
+ pulsecore/ipacl.h pulsecore/ipacl.c \
+ pulsecore/llist.h \
+ pulsecore/lock-autospawn.c pulsecore/lock-autospawn.h \
+ pulsecore/log.c pulsecore/log.h \
+ pulsecore/macro.h \
+ pulsecore/mcalign.c pulsecore/mcalign.h \
+ pulsecore/memblock.c pulsecore/memblock.h \
+ pulsecore/memblockq.c pulsecore/memblockq.h \
+ pulsecore/memchunk.c pulsecore/memchunk.h \
+ pulsecore/native-common.h \
+ pulsecore/once.c pulsecore/once.h \
+ pulsecore/packet.c pulsecore/packet.h \
+ pulsecore/parseaddr.c pulsecore/parseaddr.h \
+ pulsecore/pdispatch.c pulsecore/pdispatch.h \
+ pulsecore/pid.c pulsecore/pid.h \
+ pulsecore/pipe.c pulsecore/pipe.h \
+ pulsecore/poll.c pulsecore/poll.h \
+ pulsecore/prioq.c pulsecore/prioq.h \
+ pulsecore/proplist-util.c pulsecore/proplist-util.h \
+ pulsecore/pstream-util.c pulsecore/pstream-util.h \
+ pulsecore/pstream.c pulsecore/pstream.h \
+ pulsecore/queue.c pulsecore/queue.h \
+ pulsecore/random.c pulsecore/random.h \
+ pulsecore/rtclock.c pulsecore/rtclock.h \
+ pulsecore/shm.c pulsecore/shm.h \
+ pulsecore/socket-client.c pulsecore/socket-client.h \
+ pulsecore/socket-server.c pulsecore/socket-server.h \
+ pulsecore/socket-util.c pulsecore/socket-util.h \
+ pulsecore/strbuf.c pulsecore/strbuf.h \
+ pulsecore/strlist.c pulsecore/strlist.h \
+ pulsecore/tagstruct.c pulsecore/tagstruct.h \
+ pulsecore/time-smoother.c pulsecore/time-smoother.h \
+ pulsecore/tokenizer.c pulsecore/tokenizer.h \
+ pulsecore/winsock.h
+
+libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS = $(AM_CFLAGS)
+libpulsecommon_@PA_MAJORMINORMICRO@_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
+libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD = $(AM_LIBADD) $(LIBWRAP_LIBS) $(WINSOCK_LIBS) $(LTLIBICONV)
+
+## Please note that libpulsecommon implicitly also depends on<
+## libpulse! i.e. we have a cyclic dependancy here. Which is intended
+## since libpulse only includes stable, official APIs, while
+## libpulsecommon only includes unofficial APIs.
+
+if OS_IS_WIN32
+libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += \
+ pulsecore/mutex-win32.c pulsecore/mutex.h \
+ pulsecore/thread-win32.c pulsecore/thread.h \
+ pulsecore/semaphore-win32.c pulsecore/semaphore.h
+else
+libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += \
+ pulsecore/mutex-posix.c pulsecore/mutex.h \
+ pulsecore/thread-posix.c pulsecore/thread.h \
+ pulsecore/semaphore-posix.c pulsecore/semaphore.h
+endif
+
+if HAVE_X11
+libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/x11prop.c pulsecore/x11prop.h
+libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(X_CFLAGS)
+libpulsecommon_@PA_MAJORMINORMICRO@_la_LDFLAGS += $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS)
+endif
+
+if HAVE_LIBASYNCNS
+libpulsecommon_@PA_MAJORMINORMICRO@_la_CFLAGS += $(LIBASYNCNS_CFLAGS)
+libpulsecommon_@PA_MAJORMINORMICRO@_la_LIBADD += $(LIBASYNCNS_LIBS)
+endif
+
+if OS_IS_WIN32
+libpulsecommon_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/dllmain.c
+endif
+
###################################
# Client library #
###################################
@@ -462,11 +554,14 @@ pulseinclude_HEADERS = \
pulse/context.h \
pulse/def.h \
pulse/error.h \
+ pulse/ext-stream-restore.h \
+ pulse/gccmacro.h \
pulse/introspect.h \
- pulse/mainloop.h \
pulse/mainloop-api.h \
pulse/mainloop-signal.h \
+ pulse/mainloop.h \
pulse/operation.h \
+ pulse/proplist.h \
pulse/pulseaudio.h \
pulse/sample.h \
pulse/scache.h \
@@ -479,31 +574,24 @@ pulseinclude_HEADERS = \
pulse/util.h \
pulse/version.h \
pulse/volume.h \
- pulse/xmalloc.h \
- pulse/proplist.h \
- pulse/gccmacro.h \
- pulse/ext-stream-restore.h
-
-if HAVE_AVAHI
-pulseinclude_HEADERS += \
- pulse/browser.h
-endif
-
-if HAVE_GLIB20
-pulseinclude_HEADERS += \
- pulse/glib-mainloop.h
-endif
+ pulse/xmalloc.h
-lib_LTLIBRARIES = \
+lib_LTLIBRARIES += \
libpulse.la \
libpulse-simple.la
if HAVE_AVAHI
+pulseinclude_HEADERS += \
+ pulse/browser.h
+
lib_LTLIBRARIES += \
libpulse-browse.la
endif
if HAVE_GLIB20
+pulseinclude_HEADERS += \
+ pulse/glib-mainloop.h
+
lib_LTLIBRARIES += \
libpulse-mainloop-glib.la
endif
@@ -512,16 +600,18 @@ endif
libpulse_la_SOURCES = \
pulse/cdecl.h \
pulse/channelmap.c pulse/channelmap.h \
- pulse/client-conf.c pulse/client-conf.h \
pulse/context.c pulse/context.h \
pulse/def.h \
pulse/error.c pulse/error.h \
+ pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
+ pulse/gccmacro.h \
pulse/internal.h \
pulse/introspect.c pulse/introspect.h \
- pulse/mainloop.c pulse/mainloop.h \
pulse/mainloop-api.c pulse/mainloop-api.h \
pulse/mainloop-signal.c pulse/mainloop-signal.h \
+ pulse/mainloop.c pulse/mainloop.h \
pulse/operation.c pulse/operation.h \
+ pulse/proplist.c pulse/proplist.h \
pulse/pulseaudio.h \
pulse/sample.c pulse/sample.h \
pulse/scache.c pulse/scache.h \
@@ -532,339 +622,121 @@ libpulse_la_SOURCES = \
pulse/utf8.c pulse/utf8.h \
pulse/util.c pulse/util.h \
pulse/volume.c pulse/volume.h \
- pulse/xmalloc.c pulse/xmalloc.h \
- pulse/proplist.c pulse/proplist.h \
- pulse/ext-stream-restore.c pulse/ext-stream-restore.h \
- pulse/i18n.c pulse/i18n.h
-
-# Internal stuff that is shared with libpulsecore
-libpulse_la_SOURCES += \
- pulsecore/authkey.c pulsecore/authkey.h \
- pulsecore/conf-parser.c pulsecore/conf-parser.h \
- pulsecore/core-util.c pulsecore/core-util.h \
- pulsecore/dynarray.c pulsecore/dynarray.h \
- pulsecore/hashmap.c pulsecore/hashmap.h \
- pulsecore/idxset.c pulsecore/idxset.h \
- pulsecore/inet_ntop.c pulsecore/inet_ntop.h \
- pulsecore/iochannel.c pulsecore/iochannel.h \
- pulsecore/llist.h \
- pulsecore/log.c pulsecore/log.h \
- pulsecore/mcalign.c pulsecore/mcalign.h \
- pulsecore/memblock.c pulsecore/memblock.h \
- pulsecore/memblockq.c pulsecore/memblockq.h \
- pulsecore/memchunk.c pulsecore/memchunk.h \
- pulsecore/native-common.h \
- pulsecore/packet.c pulsecore/packet.h \
- pulsecore/parseaddr.c pulsecore/parseaddr.h \
- pulsecore/pdispatch.c pulsecore/pdispatch.h \
- pulsecore/pipe.c pulsecore/pipe.h \
- pulsecore/poll.c pulsecore/poll.h \
- pulsecore/pstream.c pulsecore/pstream.h \
- pulsecore/pstream-util.c pulsecore/pstream-util.h \
- pulsecore/queue.c pulsecore/queue.h \
- pulsecore/random.c pulsecore/random.h \
- pulsecore/socket-client.c pulsecore/socket-client.h \
- pulsecore/socket-util.c pulsecore/socket-util.h \
- pulsecore/strbuf.c pulsecore/strbuf.h \
- pulsecore/strlist.c pulsecore/strlist.h \
- pulsecore/tagstruct.c pulsecore/tagstruct.h \
- pulsecore/core-error.c pulsecore/core-error.h \
- pulsecore/winsock.h pulsecore/creds.h \
- pulsecore/shm.c pulsecore/shm.h \
- pulsecore/flist.c pulsecore/flist.h \
- pulsecore/object.c pulsecore/object.h \
- pulsecore/msgobject.c pulsecore/msgobject.h \
- pulsecore/once.c pulsecore/once.h \
- pulsecore/rtclock.c pulsecore/rtclock.h \
- pulsecore/time-smoother.c pulsecore/time-smoother.h \
- pulsecore/proplist-util.c pulsecore/proplist-util.h \
- $(PA_THREAD_OBJS)
-
-if OS_IS_WIN32
-libpulse_la_SOURCES += \
- pulsecore/dllmain.c
-endif
-
-if HAVE_X11
-libpulse_la_SOURCES += \
- pulse/client-conf-x11.c pulse/client-conf-x11.h \
- pulsecore/x11prop.c pulsecore/x11prop.h
-endif
+ pulse/xmalloc.c pulse/xmalloc.h
libpulse_la_CFLAGS = $(AM_CFLAGS)
-libpulse_la_LDFLAGS = -version-info $(LIBPULSE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
-libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV)
+libpulse_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPULSE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
+libpulse_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) $(LTLIBICONV) libpulsecommon-@PA_MAJORMINORMICRO@.la
if HAVE_X11
+libpulse_la_SOURCES += pulse/client-conf-x11.c pulse/client-conf-x11.h
libpulse_la_CFLAGS += $(X_CFLAGS)
libpulse_la_LDFLAGS += $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS)
endif
-if HAVE_LIBASYNCNS
-libpulse_la_CFLAGS += $(LIBASYNCNS_CFLAGS)
-libpulse_la_LIBADD += $(LIBASYNCNS_LIBS)
-endif
-
-libpulse_simple_la_SOURCES = \
- pulse/simple.c pulse/simple.h \
- pulsecore/log.c pulsecore/log.h \
- pulsecore/core-util.c pulsecore/core-util.h \
- pulsecore/core-error.c pulsecore/core-error.h \
- pulsecore/once.c pulsecore/once.h \
- $(PA_THREAD_OBJS)
-
+libpulse_simple_la_SOURCES = pulse/simple.c pulse/simple.h
libpulse_simple_la_CFLAGS = $(AM_CFLAGS)
-libpulse_simple_la_LIBADD = $(AM_LIBADD) libpulse.la
-libpulse_simple_la_LDFLAGS = -version-info $(LIBPULSE_SIMPLE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
+libpulse_simple_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+libpulse_simple_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPULSE_SIMPLE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
-libpulse_browse_la_SOURCES = pulse/browser.c pulse/browser.h pulsecore/avahi-wrap.c pulsecore/avahi-wrap.h 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)
+libpulse_browse_la_SOURCES = pulse/browser.c pulse/browser.h pulsecore/avahi-wrap.c pulsecore/avahi-wrap.h
libpulse_browse_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
-libpulse_browse_la_LIBADD = $(AM_LIBADD) libpulse.la $(AVAHI_LIBS)
-libpulse_browse_la_LDFLAGS = -version-info $(LIBPULSE_BROWSE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
+libpulse_browse_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(AVAHI_LIBS)
+libpulse_browse_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPULSE_BROWSE_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
-libpulse_mainloop_glib_la_SOURCES = \
- pulse/glib-mainloop.h pulse/glib-mainloop.c \
- pulsecore/log.c pulsecore/log.h \
- pulsecore/core-util.c pulsecore/core-util.h \
- pulsecore/core-error.c pulsecore/core-error.h \
- pulsecore/once.c pulsecore/once.h \
- $(PA_THREAD_OBJS)
+libpulse_mainloop_glib_la_SOURCES = pulse/glib-mainloop.h pulse/glib-mainloop.c
libpulse_mainloop_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB20_CFLAGS)
-libpulse_mainloop_glib_la_LIBADD = $(AM_LIBADD) libpulse.la $(GLIB20_LIBS)
-libpulse_mainloop_glib_la_LDFLAGS = -version-info $(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
+libpulse_mainloop_glib_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la $(GLIB20_LIBS)
+libpulse_mainloop_glib_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBPULSE_MAINLOOP_GLIB_VERSION_INFO) -Wl,-version-script=$(srcdir)/map-file
###################################
# OSS emulation #
###################################
if HAVE_OSS
-
lib_LTLIBRARIES += libpulsedsp.la
-
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
libpulsedsp_la_CFLAGS = $(AM_CFLAGS)
-libpulsedsp_la_LIBADD = $(AM_LIBADD) libpulse.la
-libpulsedsp_la_LDFLAGS = -avoid-version
-
-###################################
-# ffmpeg resampler #
-###################################
-
-noinst_LTLIBRARIES = libffmpeg-resampler.la
-
-libffmpeg_resampler_la_CPPFLAGS = $(AM_CPPFLAGS)
-libffmpeg_resampler_la_SOURCES = pulsecore/ffmpeg/resample2.c pulsecore/ffmpeg/avcodec.h pulsecore/ffmpeg/dsputil.h
+libpulsedsp_la_LIBADD = $(AM_LIBADD) libpulse.la libpulsecommon-@PA_MAJORMINORMICRO@.la
+libpulsedsp_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version
###################################
# Daemon core library #
###################################
-#pulsecoreinclude_HEADERS =
-noinst_HEADERS = \
- pulsecore/autoload.h \
- pulsecore/atomic.h \
- pulsecore/cli-command.h \
- pulsecore/cli-text.h \
- pulsecore/client.h \
- pulsecore/core.h \
- pulsecore/core-scache.h \
- pulsecore/core-subscribe.h \
- pulsecore/conf-parser.h \
- pulsecore/core-util.h \
- pulsecore/dynarray.h \
- pulsecore/g711.h \
- pulsecore/hashmap.h \
- pulsecore/idxset.h \
- pulsecore/log.h \
- pulsecore/mcalign.h \
- pulsecore/memblock.h \
- pulsecore/memblockq.h \
- pulsecore/memchunk.h \
- pulsecore/modargs.h \
- pulsecore/modinfo.h \
- pulsecore/module.h \
- pulsecore/namereg.h \
- pulsecore/pid.h \
- pulsecore/play-memchunk.h \
- pulsecore/play-memblockq.h \
- pulsecore/shared.h \
- pulsecore/queue.h \
- pulsecore/random.h \
- pulsecore/resampler.h \
- pulsecore/sample-util.h \
- pulsecore/sconv.h \
- pulsecore/sink.h \
- pulsecore/sink-input.h \
- pulsecore/sioman.h \
- pulsecore/sound-file.h \
- pulsecore/sound-file-stream.h \
- pulsecore/source.h \
- pulsecore/source-output.h \
- pulsecore/strbuf.h \
- pulsecore/tokenizer.h \
- pulsecore/creds.h \
- pulsecore/shm.h \
- pulsecore/llist.h \
- pulsecore/refcnt.h \
- pulsecore/mutex.h \
- pulsecore/thread.h \
- pulsecore/semaphore.h \
- pulsecore/once.h
-
-lib_LTLIBRARIES += libpulsecore.la
-
-# Some public stuff is used even in the core
-libpulsecore_la_SOURCES = \
- pulse/channelmap.c pulse/channelmap.h \
- pulse/error.c pulse/error.h \
- pulse/mainloop.c pulse/mainloop.h \
- pulse/mainloop-api.c pulse/mainloop-api.h \
- pulse/mainloop-signal.c pulse/mainloop-signal.h \
- pulse/sample.c pulse/sample.h \
- pulse/timeval.c pulse/timeval.h \
- pulse/utf8.c pulse/utf8.h \
- pulse/util.c pulse/util.h \
- pulse/volume.c pulse/volume.h \
- pulse/xmalloc.c pulse/xmalloc.h \
- pulse/proplist.c pulse/proplist.h \
- pulse/i18n.c pulse/i18n.h
+lib_LTLIBRARIES += libpulsecore-@PA_MAJORMINORMICRO@.la
-# Pure core stuff (some are shared in libpulse though).
-libpulsecore_la_SOURCES += \
+# Pure core stuff
+libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES = \
+ pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \
+ pulsecore/asyncq.c pulsecore/asyncq.h \
+ pulsecore/auth-cookie.c pulsecore/auth-cookie.h \
pulsecore/autoload.c pulsecore/autoload.h \
pulsecore/cli-command.c pulsecore/cli-command.h \
pulsecore/cli-text.c pulsecore/cli-text.h \
pulsecore/client.c pulsecore/client.h \
- pulsecore/conf-parser.c pulsecore/conf-parser.h \
- pulsecore/core.c pulsecore/core.h \
pulsecore/core-scache.c pulsecore/core-scache.h \
pulsecore/core-subscribe.c pulsecore/core-subscribe.h \
- pulsecore/core-util.c pulsecore/core-util.h \
- pulsecore/dynarray.c pulsecore/dynarray.h \
- pulsecore/endianmacros.h \
+ pulsecore/core.c pulsecore/core.h \
+ pulsecore/envelope.c pulsecore/envelope.h \
+ pulsecore/fdsem.c pulsecore/fdsem.h \
+ pulsecore/ffmpeg/resample2.c pulsecore/ffmpeg/avcodec.h pulsecore/ffmpeg/dsputil.h \
pulsecore/g711.c pulsecore/g711.h \
- pulsecore/hashmap.c pulsecore/hashmap.h \
- pulsecore/idxset.c pulsecore/idxset.h \
- pulsecore/log.c pulsecore/log.h \
- pulsecore/mcalign.c pulsecore/mcalign.h \
- pulsecore/memblock.c pulsecore/memblock.h \
- pulsecore/memblockq.c pulsecore/memblockq.h \
- pulsecore/memchunk.c pulsecore/memchunk.h \
+ pulsecore/hook-list.c pulsecore/hook-list.h \
+ pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \
pulsecore/modargs.c pulsecore/modargs.h \
pulsecore/modinfo.c pulsecore/modinfo.h \
- pulsecore/ltdl-helper.c pulsecore/ltdl-helper.h \
pulsecore/module.c pulsecore/module.h \
+ pulsecore/msgobject.c pulsecore/msgobject.h \
pulsecore/namereg.c pulsecore/namereg.h \
- pulsecore/pid.c pulsecore/pid.h \
- pulsecore/pipe.c pulsecore/pipe.h \
- pulsecore/play-memchunk.c pulsecore/play-memchunk.h \
+ pulsecore/object.c pulsecore/object.h \
pulsecore/play-memblockq.c pulsecore/play-memblockq.h \
- pulsecore/poll.c pulsecore/poll.h \
- pulsecore/shared.c pulsecore/shared.h \
- pulsecore/queue.c pulsecore/queue.h \
- pulsecore/random.c pulsecore/random.h \
+ pulsecore/play-memchunk.c pulsecore/play-memchunk.h \
pulsecore/resampler.c pulsecore/resampler.h \
+ pulsecore/rtpoll.c pulsecore/rtpoll.h \
+ pulsecore/rtsig.c pulsecore/rtsig.h \
pulsecore/sample-util.c pulsecore/sample-util.h \
- pulsecore/sconv.c pulsecore/sconv.h \
pulsecore/sconv-s16be.c pulsecore/sconv-s16be.h \
pulsecore/sconv-s16le.c pulsecore/sconv-s16le.h \
- pulsecore/sink.c pulsecore/sink.h \
+ pulsecore/sconv.c pulsecore/sconv.h \
+ pulsecore/shared.c pulsecore/shared.h \
+ pulsecore/shm.c pulsecore/shm.h \
pulsecore/sink-input.c pulsecore/sink-input.h \
+ pulsecore/sink.c pulsecore/sink.h \
pulsecore/sioman.c pulsecore/sioman.h \
- pulsecore/sound-file.c pulsecore/sound-file.h \
pulsecore/sound-file-stream.c pulsecore/sound-file-stream.h \
- pulsecore/source.c pulsecore/source.h \
+ pulsecore/sound-file.c pulsecore/sound-file.h \
pulsecore/source-output.c pulsecore/source-output.h \
- pulsecore/strbuf.c pulsecore/strbuf.h \
- pulsecore/tokenizer.c pulsecore/tokenizer.h \
- pulsecore/winsock.h \
- pulsecore/core-error.c pulsecore/core-error.h \
- pulsecore/hook-list.c pulsecore/hook-list.h \
- pulsecore/shm.c pulsecore/shm.h \
- pulsecore/flist.c pulsecore/flist.h \
- pulsecore/asyncmsgq.c pulsecore/asyncmsgq.h \
- pulsecore/asyncq.c pulsecore/asyncq.h \
- pulsecore/thread-mq.c pulsecore/thread-mq.h \
- pulsecore/fdsem.c pulsecore/fdsem.h \
- pulsecore/object.c pulsecore/object.h \
- pulsecore/msgobject.c pulsecore/msgobject.h \
- pulsecore/rtsig.c pulsecore/rtsig.h \
- pulsecore/rtpoll.c pulsecore/rtpoll.h \
- pulsecore/rtclock.c pulsecore/rtclock.h \
- pulsecore/macro.h \
- pulsecore/once.c pulsecore/once.h \
- pulsecore/time-smoother.c pulsecore/time-smoother.h \
+ pulsecore/source.c pulsecore/source.h \
pulsecore/start-child.c pulsecore/start-child.h \
- pulsecore/envelope.c pulsecore/envelope.h \
- pulsecore/proplist-util.c pulsecore/proplist-util.h \
- $(PA_THREAD_OBJS)
+ pulsecore/thread-mq.c pulsecore/thread-mq.h \
+ pulsecore/time-smoother.c pulsecore/time-smoother.h
-if OS_IS_WIN32
-libpulsecore_la_SOURCES += \
- pulsecore/dllmain.c
-endif
+libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS = $(AM_CFLAGS) $(LIBOIL_CFLAGS)
+libpulsecore_@PA_MAJORMINORMICRO@_la_LDFLAGS = -avoid-version
+libpulsecore_@PA_MAJORMINORMICRO@_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LTLIBICONV) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-libpulsecore_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBOIL_CFLAGS)
-libpulsecore_la_LDFLAGS = -version-info $(LIBPULSECORE_VERSION_INFO)
-libpulsecore_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) $(LIBSAMPLERATE_LIBS) $(LIBSNDFILE_LIBS) $(LIBSPEEX_LIBS) $(WINSOCK_LIBS) $(LIBOIL_LIBS) $(LTLIBICONV) libffmpeg-resampler.la
+if HAVE_X11
+libpulsecore_@PA_MAJORMINORMICRO@_la_SOURCES += pulsecore/x11wrap.c pulsecore/x11wrap.h
+libpulsecore_@PA_MAJORMINORMICRO@_la_CFLAGS += $(X_CFLAGS)
+libpulsecore_@PA_MAJORMINORMICRO@_la_LDFLAGS += $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS)
+endif
###################################
# Plug-in support libraries #
###################################
-#pulsecoreinclude_HEADERS +=
-noinst_HEADERS += \
- pulsecore/socket-util.h \
- pulsecore/iochannel.h \
- pulsecore/socket-server.h \
- pulsecore/ipacl.h \
- pulsecore/socket-client.h \
- pulsecore/parseaddr.h \
- pulsecore/packet.h \
- pulsecore/pstream.h \
- pulsecore/ioline.h \
- pulsecore/cli.h \
- pulsecore/protocol-cli.h \
- pulsecore/tagstruct.h \
- pulsecore/pstream-util.h \
- pulsecore/pdispatch.h \
- pulsecore/authkey.h \
- pulsecore/auth-cookie.h \
- pulsecore/strlist.h \
- pulsecore/protocol-simple.h \
- pulsecore/esound.h \
- pulsecore/protocol-esound.h \
- pulsecore/native-common.h \
- pulsecore/protocol-native.h \
- pulsecore/protocol-http.h
-
### Warning! Due to an obscure bug in libtool/automake it is required
### that the libraries in modlibexec_LTLIBRARIES are specified in-order,
### i.e. libraries near the end of the list depend on libraries near
### the head, and not the other way!
modlibexec_LTLIBRARIES = \
- libsocket-util.la \
- libiochannel.la \
- libsocket-server.la \
- libipacl.la \
- libparseaddr.la \
- libsocket-client.la \
- libpacket.la \
- libpstream.la \
- libioline.la \
libcli.la \
libprotocol-cli.la \
- libtagstruct.la \
- libpstream-util.la \
- libpdispatch.la \
- libauthkey.la \
- libauth-cookie.la \
- libstrlist.la \
libprotocol-simple.la \
libprotocol-http.la \
libprotocol-native.la \
@@ -876,146 +748,63 @@ modlibexec_LTLIBRARIES += \
librtp.la
endif
-if HAVE_X11
-#pulsecoreinclude_HEADERS +=
-noinst_HEADERS += \
- pulsecore/x11wrap.h \
- pulsecore/x11prop.h
-
-modlibexec_LTLIBRARIES += \
- libx11wrap.la \
- libx11prop.la
-endif
-
if HAVE_AVAHI
-#pulsecoreinclude_HEADERS +=
-noinst_HEADERS += \
- pulsecore/avahi-wrap.h
-
modlibexec_LTLIBRARIES += \
libavahi-wrap.la
endif
libprotocol_simple_la_SOURCES = pulsecore/protocol-simple.c pulsecore/protocol-simple.h
libprotocol_simple_la_LDFLAGS = -avoid-version
-libprotocol_simple_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-server.la libiochannel.la
-
-libsocket_server_la_SOURCES = \
- pulsecore/inet_ntop.c pulsecore/inet_ntop.h \
- pulsecore/inet_pton.c pulsecore/inet_pton.h \
- pulsecore/socket-server.c pulsecore/socket-server.h
-libsocket_server_la_LDFLAGS = -avoid-version
-libsocket_server_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-util.la $(LIBWRAP_LIBS) $(WINSOCK_LIBS)
-
-libipacl_la_SOURCES = pulsecore/ipacl.h pulsecore/ipacl.c \
- pulsecore/inet_pton.c pulsecore/inet_pton.h
-libipacl_la_LDFLAGS = -avoid-version
-libipacl_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(WINSOCK_LIBS)
-
-libsocket_client_la_SOURCES = pulsecore/socket-client.c pulsecore/socket-client.h
-libsocket_client_la_LDFLAGS = -avoid-version
-libsocket_client_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-util.la libparseaddr.la $(LIBASYNCNS_LIBS) $(WINSOCK_LIBS)
-libsocket_client_la_CFLAGS = $(AM_CFLAGS) $(LIBASYNCNS_CFLAGS)
-
-libparseaddr_la_SOURCES = pulsecore/parseaddr.c pulsecore/parseaddr.h
-libparseaddr_la_LDFLAGS = -avoid-version
-libparseaddr_la_LIBADD = $(AM_LIBADD) libpulsecore.la
-
-libpstream_la_SOURCES = pulsecore/pstream.c pulsecore/pstream.h
-libpstream_la_LDFLAGS = -avoid-version
-libpstream_la_LIBADD = $(AM_LIBADD) libpulsecore.la libpacket.la libiochannel.la $(WINSOCK_LIBS)
-
-libpstream_util_la_SOURCES = pulsecore/pstream-util.c pulsecore/pstream-util.h
-libpstream_util_la_LDFLAGS = -avoid-version
-libpstream_util_la_LIBADD = $(AM_LIBADD) libpacket.la libpstream.la libtagstruct.la libpulsecore.la
-
-libpdispatch_la_SOURCES = pulsecore/pdispatch.c pulsecore/pdispatch.h
-libpdispatch_la_LDFLAGS = -avoid-version
-libpdispatch_la_LIBADD = $(AM_LIBADD) libtagstruct.la libpulsecore.la
-
-libiochannel_la_SOURCES = pulsecore/iochannel.c pulsecore/iochannel.h
-libiochannel_la_LDFLAGS = -avoid-version
-libiochannel_la_LIBADD = $(AM_LIBADD) libsocket-util.la libpulsecore.la $(WINSOCK_LIBS)
-
-libpacket_la_SOURCES = pulsecore/packet.c pulsecore/packet.h
-libpacket_la_LDFLAGS = -avoid-version
-libpacket_la_LIBADD = $(AM_LIBADD) libpulsecore.la
-
-libioline_la_SOURCES = pulsecore/ioline.c pulsecore/ioline.h
-libioline_la_LDFLAGS = -avoid-version
-libioline_la_LIBADD = $(AM_LIBADD) libiochannel.la libpulsecore.la
+libprotocol_simple_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libcli_la_SOURCES = pulsecore/cli.c pulsecore/cli.h
-libcli_la_CPPFLAGS = $(AM_CPPFLAGS)
libcli_la_LDFLAGS = -avoid-version
-libcli_la_LIBADD = $(AM_LIBADD) libiochannel.la libioline.la libpulsecore.la
-
-libstrlist_la_SOURCES = pulsecore/strlist.c pulsecore/strlist.h
-libstrlist_la_LDFLAGS = -avoid-version
-libstrlist_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+libcli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libprotocol_cli_la_SOURCES = pulsecore/protocol-cli.c pulsecore/protocol-cli.h
libprotocol_cli_la_LDFLAGS = -avoid-version
-libprotocol_cli_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la libcli.la libpulsecore.la
+libprotocol_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libprotocol_http_la_SOURCES = pulsecore/protocol-http.c pulsecore/protocol-http.h
libprotocol_http_la_LDFLAGS = -avoid-version
-libprotocol_http_la_LIBADD = $(AM_LIBADD) libsocket-server.la libioline.la libpulsecore.la libiochannel.la
+libprotocol_http_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libprotocol_native_la_SOURCES = pulsecore/protocol-native.c pulsecore/protocol-native.h pulsecore/native-common.h
libprotocol_native_la_LDFLAGS = -avoid-version
-libprotocol_native_la_LIBADD = $(AM_LIBADD) libsocket-server.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauth-cookie.la libstrlist.la libpulsecore.la libiochannel.la libipacl.la
-
-libtagstruct_la_SOURCES = pulsecore/tagstruct.c pulsecore/tagstruct.h
-libtagstruct_la_LDFLAGS = -avoid-version
-libtagstruct_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(WINSOCK_LIBS)
+libprotocol_native_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libprotocol_esound_la_SOURCES = pulsecore/protocol-esound.c pulsecore/protocol-esound.h pulsecore/esound.h
libprotocol_esound_la_LDFLAGS = -avoid-version
-libprotocol_esound_la_LIBADD = $(AM_LIBADD) libsocket-server.la libiochannel.la libauthkey.la libauth-cookie.la libpulsecore.la libipacl.la
-
-libauthkey_la_SOURCES = pulsecore/authkey.c pulsecore/authkey.h
-libauthkey_la_LDFLAGS = -avoid-version
-libauthkey_la_LIBADD = $(AM_LIBADD) libpulsecore.la
-
-libauth_cookie_la_SOURCES = pulsecore/auth-cookie.c pulsecore/auth-cookie.h
-libauth_cookie_la_LDFLAGS = -avoid-version
-libauth_cookie_la_LIBADD = $(AM_LIBADD) libauthkey.la libpulsecore.la
-
-libsocket_util_la_SOURCES = \
- pulsecore/inet_ntop.c pulsecore/inet_ntop.h \
- pulsecore/socket-util.c pulsecore/socket-util.h
-libsocket_util_la_LDFLAGS = -avoid-version
-libsocket_util_la_LIBADD = $(AM_LIBADD) $(WINSOCK_LIBS) libpulsecore.la
-
-librtp_la_SOURCES = modules/rtp/rtp.c modules/rtp/rtp.h modules/rtp/sdp.c modules/rtp/sdp.h modules/rtp/sap.c modules/rtp/sap.h
+libprotocol_esound_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+
+librtp_la_SOURCES = \
+ modules/rtp/rtp.c modules/rtp/rtp.h \
+ modules/rtp/sdp.c modules/rtp/sdp.h \
+ modules/rtp/sap.c modules/rtp/sap.h \
+ modules/rtp/rtsp_client.c modules/rtp/rtsp_client.h \
+ modules/rtp/headerlist.c modules/rtp/headerlist.h
librtp_la_LDFLAGS = -avoid-version
-librtp_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+librtp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
-# X11
-
-libx11wrap_la_SOURCES = pulsecore/x11wrap.c pulsecore/x11wrap.h
-libx11wrap_la_LDFLAGS = -avoid-version
-libx11wrap_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
-libx11wrap_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libpulsecore.la
-
-libx11prop_la_SOURCES = pulsecore/x11prop.c pulsecore/x11prop.h
-libx11prop_la_LDFLAGS = -avoid-version
-libx11prop_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
-libx11prop_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS)
+libraop_la_SOURCES = \
+ modules/raop/raop_client.c modules/raop/raop_client.h \
+ modules/raop/base64.c modules/raop/base64.h
+libraop_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS)
+libraop_la_LDFLAGS = -avoid-version
+libraop_la_LIBADD = $(AM_LIBADD) $(OPENSSL_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# Avahi
-
libavahi_wrap_la_SOURCES = pulsecore/avahi-wrap.c pulsecore/avahi-wrap.h
libavahi_wrap_la_LDFLAGS = -avoid-version
libavahi_wrap_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
-libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore.la
+libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
###################################
# Plug-in libraries #
###################################
modlibexec_LTLIBRARIES += \
+ module-flat-volume.la \
module-cli.la \
module-cli-protocol-tcp.la \
module-simple-protocol-tcp.la \
@@ -1151,12 +940,27 @@ 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
+if HAVE_OPENSSL
+modlibexec_LTLIBRARIES += \
+ libraop.la \
+ module-raop-sink.la
+if HAVE_AVAHI
+modlibexec_LTLIBRARIES += \
+ module-raop-discover.la
+endif
+endif
+
+
# These are generated by a M4 script
SYMDEF_FILES = \
@@ -1210,10 +1014,15 @@ 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/module-raop-sink-symdef.h \
+ modules/module-raop-discover-symdef.h \
modules/gconf/module-gconf-symdef.h \
modules/module-position-event-sounds-symdef.h \
- modules/module-console-kit-symdef.h
+ modules/module-console-kit-symdef.h \
+ modules/module-flat-volume-symdef.h
EXTRA_DIST += $(SYMDEF_FILES)
BUILT_SOURCES += $(SYMDEF_FILES)
@@ -1222,334 +1031,373 @@ $(SYMDEF_FILES): modules/module-defs.h.m4
$(MKDIR_P) modules
$(MKDIR_P) modules/gconf
$(MKDIR_P) modules/rtp
+ $(MKDIR_P) modules/bluetooth
$(M4) -Dfname="$@" $< > $@
+# Flat volume
+
+module_flat_volume_la_SOURCES = modules/module-flat-volume.c
+module_flat_volume_la_LDFLAGS = -module -avoid-version
+module_flat_volume_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+
# Simple protocol
module_simple_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
module_simple_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS)
module_simple_protocol_tcp_la_LDFLAGS = -module -avoid-version
-module_simple_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-simple.la libsocket-server.la
+module_simple_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_simple_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
module_simple_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_SIMPLE $(AM_CFLAGS)
module_simple_protocol_unix_la_LDFLAGS = -module -avoid-version
-module_simple_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-simple.la libsocket-server.la libsocket-util.la
+module_simple_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-simple.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# CLI protocol
module_cli_la_SOURCES = modules/module-cli.c
module_cli_la_LDFLAGS = -module -avoid-version
-module_cli_la_LIBADD = $(AM_LIBADD) libcli.la libiochannel.la libpulsecore.la
+module_cli_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libcli.la
module_cli_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
module_cli_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS)
module_cli_protocol_tcp_la_LDFLAGS = -module -avoid-version
-module_cli_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-cli.la libsocket-server.la
+module_cli_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-cli.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_cli_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
module_cli_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_CLI $(AM_CFLAGS)
module_cli_protocol_unix_la_LDFLAGS = -module -avoid-version
-module_cli_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-cli.la libsocket-server.la libsocket-util.la
+module_cli_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-cli.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# HTTP protocol
module_http_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
module_http_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS)
module_http_protocol_tcp_la_LDFLAGS = -module -avoid-version
-module_http_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-http.la libsocket-server.la
+module_http_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-http.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_http_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
module_http_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_HTTP $(AM_CFLAGS)
module_http_protocol_unix_la_LDFLAGS = -module -avoid-version
-module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-http.la libsocket-server.la libsocket-util.la
+module_http_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-http.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# Native protocol
module_native_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
module_native_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS)
module_native_protocol_tcp_la_LDFLAGS = -module -avoid-version
-module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la
+module_native_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-native.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_native_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
module_native_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_NATIVE $(AM_CFLAGS)
module_native_protocol_unix_la_LDFLAGS = -module -avoid-version
-module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la
+module_native_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-native.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_native_protocol_fd_la_SOURCES = modules/module-native-protocol-fd.c
module_native_protocol_fd_la_CFLAGS = $(AM_CFLAGS)
module_native_protocol_fd_la_LDFLAGS = -module -avoid-version
-module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-native.la libsocket-server.la libsocket-util.la libiochannel.la
+module_native_protocol_fd_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-native.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# EsounD protocol
module_esound_protocol_tcp_la_SOURCES = modules/module-protocol-stub.c
module_esound_protocol_tcp_la_CFLAGS = -DUSE_TCP_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS)
module_esound_protocol_tcp_la_LDFLAGS = -module -avoid-version
-module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la
+module_esound_protocol_tcp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-esound.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_esound_protocol_unix_la_SOURCES = modules/module-protocol-stub.c
module_esound_protocol_unix_la_CFLAGS = -DUSE_UNIX_SOCKETS -DUSE_PROTOCOL_ESOUND $(AM_CFLAGS)
module_esound_protocol_unix_la_LDFLAGS = -module -avoid-version
-module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore.la libprotocol-esound.la libsocket-server.la libsocket-util.la
+module_esound_protocol_unix_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libprotocol-esound.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_esound_compat_spawnfd_la_SOURCES = modules/module-esound-compat-spawnfd.c
module_esound_compat_spawnfd_la_LDFLAGS = -module -avoid-version
-module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_esound_compat_spawnfd_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_esound_compat_spawnpid_la_SOURCES = modules/module-esound-compat-spawnpid.c
module_esound_compat_spawnpid_la_LDFLAGS = -module -avoid-version
-module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_esound_compat_spawnpid_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_esound_sink_la_SOURCES = modules/module-esound-sink.c
module_esound_sink_la_LDFLAGS = -module -avoid-version
-module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la libsocket-client.la libauthkey.la libsocket-util.la
+module_esound_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# Pipes
module_pipe_sink_la_SOURCES = modules/module-pipe-sink.c
module_pipe_sink_la_LDFLAGS = -module -avoid-version
-module_pipe_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la
+module_pipe_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_pipe_source_la_SOURCES = modules/module-pipe-source.c
module_pipe_source_la_LDFLAGS = -module -avoid-version
-module_pipe_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la libiochannel.la
+module_pipe_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# Fake sources/sinks
module_sine_la_SOURCES = modules/module-sine.c
module_sine_la_LDFLAGS = -module -avoid-version
-module_sine_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_sine_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_null_sink_la_SOURCES = modules/module-null-sink.c
module_null_sink_la_LDFLAGS = -module -avoid-version
-module_null_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_null_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# Couplings
module_combine_la_SOURCES = modules/module-combine.c
module_combine_la_LDFLAGS = -module -avoid-version
-module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_combine_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_remap_sink_la_SOURCES = modules/module-remap-sink.c
module_remap_sink_la_LDFLAGS = -module -avoid-version
-module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_remap_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_ladspa_sink_la_SOURCES = modules/module-ladspa-sink.c modules/ladspa.h
module_ladspa_sink_la_CFLAGS = -DLADSPA_PATH=\"$(libdir)/ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa:/usr/local/lib64/ladspa:/usr/lib64/ladspa\" $(AM_CFLAGS)
module_ladspa_sink_la_LDFLAGS = -module -avoid-version
-module_ladspa_sink_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) libpulsecore.la
+module_ladspa_sink_la_LIBADD = $(AM_LIBADD) $(LIBLTDL) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_match_la_SOURCES = modules/module-match.c
module_match_la_LDFLAGS = -module -avoid-version
-module_match_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_match_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_tunnel_sink_la_SOURCES = modules/module-tunnel.c
module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS)
module_tunnel_sink_la_LDFLAGS = -module -avoid-version
-module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauth-cookie.la libsocket-util.la libiochannel.la
+module_tunnel_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_tunnel_source_la_SOURCES = modules/module-tunnel.c
module_tunnel_source_la_LDFLAGS = -module -avoid-version
-module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la libsocket-client.la libpstream.la libpstream-util.la libpdispatch.la libtagstruct.la libauthkey.la libauth-cookie.la libsocket-util.la libiochannel.la
+module_tunnel_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# X11
module_x11_bell_la_SOURCES = modules/module-x11-bell.c
module_x11_bell_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
module_x11_bell_la_LDFLAGS = -module -avoid-version
-module_x11_bell_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libx11wrap.la libpulsecore.la
+module_x11_bell_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_x11_publish_la_SOURCES = modules/module-x11-publish.c
module_x11_publish_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
module_x11_publish_la_LDFLAGS = -module -avoid-version
-module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libx11wrap.la libauthkey.la libauth-cookie.la libx11prop.la libstrlist.la libpulsecore.la
+module_x11_publish_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_x11_xsmp_la_SOURCES = modules/module-x11-xsmp.c
module_x11_xsmp_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS)
module_x11_xsmp_la_LDFLAGS = -module -avoid-version
-module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libx11wrap.la libpulsecore.la
+module_x11_xsmp_la_LIBADD = $(AM_LIBADD) $(X_PRE_LIBS) -lX11 $(X_LIBS) $(X_EXTRA_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# OSS
liboss_util_la_SOURCES = modules/oss-util.c modules/oss-util.h
liboss_util_la_LDFLAGS = -avoid-version
-liboss_util_la_LIBADD = libpulsecore.la
+liboss_util_la_LIBADD = libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_oss_la_SOURCES = modules/module-oss.c
module_oss_la_LDFLAGS = -module -avoid-version
-module_oss_la_LIBADD = $(AM_LIBADD) libiochannel.la liboss-util.la libpulsecore.la
+module_oss_la_LIBADD = $(AM_LIBADD) liboss-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# ALSA
libalsa_util_la_SOURCES = modules/alsa-util.c modules/alsa-util.h
libalsa_util_la_LDFLAGS = -avoid-version
-libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore.la
+libalsa_util_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
module_alsa_sink_la_SOURCES = modules/module-alsa-sink.c
module_alsa_sink_la_LDFLAGS = -module -avoid-version
-module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la
+module_alsa_sink_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_alsa_sink_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
module_alsa_source_la_SOURCES = modules/module-alsa-source.c
module_alsa_source_la_LDFLAGS = -module -avoid-version
-module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore.la
+module_alsa_source_la_LIBADD = $(AM_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_alsa_source_la_CFLAGS = $(AM_CFLAGS) $(ASOUNDLIB_CFLAGS)
# Solaris
module_solaris_la_SOURCES = modules/module-solaris.c
module_solaris_la_LDFLAGS = -module -avoid-version
-module_solaris_la_LIBADD = $(AM_LIBADD) libiochannel.la libpulsecore.la
+module_solaris_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
# Avahi
module_zeroconf_publish_la_SOURCES = modules/module-zeroconf-publish.c
module_zeroconf_publish_la_LDFLAGS = -module -avoid-version
-module_zeroconf_publish_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore.la
+module_zeroconf_publish_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_zeroconf_publish_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
module_zeroconf_discover_la_SOURCES = modules/module-zeroconf-discover.c
module_zeroconf_discover_la_LDFLAGS = -module -avoid-version
-module_zeroconf_discover_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore.la
+module_zeroconf_discover_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_zeroconf_discover_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
# LIRC
module_lirc_la_SOURCES = modules/module-lirc.c
module_lirc_la_LDFLAGS = -module -avoid-version
-module_lirc_la_LIBADD = $(AM_LIBADD) $(LIRC_LIBS) libpulsecore.la
+module_lirc_la_LIBADD = $(AM_LIBADD) $(LIRC_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_lirc_la_CFLAGS = $(AM_CFLAGS) $(LIRC_CFLAGS)
# Linux evdev
module_mmkbd_evdev_la_SOURCES = modules/module-mmkbd-evdev.c
module_mmkbd_evdev_la_LDFLAGS = -module -avoid-version
-module_mmkbd_evdev_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_mmkbd_evdev_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_mmkbd_evdev_la_CFLAGS = $(AM_CFLAGS)
# Windows waveout
#module_waveout_la_SOURCES = modules/module-waveout.c
#module_waveout_la_LDFLAGS = -module -avoid-version
-#module_waveout_la_LIBADD = $(AM_LIBADD) libpulsecore.la -lwinmm
+#module_waveout_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la -lwinmm libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
#module_waveout_la_CFLAGS = $(AM_CFLAGS)
# Hardware autodetection module
module_detect_la_SOURCES = modules/module-detect.c
module_detect_la_LDFLAGS = -module -avoid-version
-module_detect_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_detect_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_detect_la_CFLAGS = $(AM_CFLAGS)
# Volume restore module
module_volume_restore_la_SOURCES = modules/module-volume-restore.c
module_volume_restore_la_LDFLAGS = -module -avoid-version
-module_volume_restore_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_volume_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_volume_restore_la_CFLAGS = $(AM_CFLAGS)
# Position event sounds in space
module_position_event_sounds_la_SOURCES = modules/module-position-event-sounds.c
module_position_event_sounds_la_LDFLAGS = -module -avoid-version
-module_position_event_sounds_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_position_event_sounds_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_position_event_sounds_CFLAGS = $(AM_CFLAGS)
# Device volume/muted restore module
module_device_restore_la_SOURCES = modules/module-device-restore.c
module_device_restore_la_LDFLAGS = -module -avoid-version
-module_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore.la -lgdbm
+module_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la -lgdbm libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_device_restore_la_CFLAGS = $(AM_CFLAGS)
# Stream volume/muted/device restore module
module_stream_restore_la_SOURCES = modules/module-stream-restore.c
module_stream_restore_la_LDFLAGS = -module -avoid-version
-module_stream_restore_la_LIBADD = $(AM_LIBADD) libpulsecore.la -lgdbm
+module_stream_restore_la_LIBADD = $(AM_LIBADD) libprotocol-native.la libpulsecore-@PA_MAJORMINORMICRO@.la -lgdbm libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_stream_restore_la_CFLAGS = $(AM_CFLAGS)
# Default sink/source restore module
module_default_device_restore_la_SOURCES = modules/module-default-device-restore.c
module_default_device_restore_la_LDFLAGS = -module -avoid-version
-module_default_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_default_device_restore_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_default_device_restore_la_CFLAGS = $(AM_CFLAGS)
# Always Sink module
module_always_sink_la_SOURCES = modules/module-always-sink.c
module_always_sink_la_LDFLAGS = -module -avoid-version
-module_always_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_always_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_always_sink_la_CFLAGS = $(AM_CFLAGS)
# Rescue streams module
module_rescue_streams_la_SOURCES = modules/module-rescue-streams.c
module_rescue_streams_la_LDFLAGS = -module -avoid-version
-module_rescue_streams_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_rescue_streams_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_rescue_streams_la_CFLAGS = $(AM_CFLAGS)
# Suspend-on-idle module
module_suspend_on_idle_la_SOURCES = modules/module-suspend-on-idle.c
module_suspend_on_idle_la_LDFLAGS = -module -avoid-version
-module_suspend_on_idle_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_suspend_on_idle_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS)
# RTP modules
module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c
module_rtp_send_la_LDFLAGS = -module -avoid-version
-module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la libsocket-util.la
+module_rtp_send_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_rtp_send_la_CFLAGS = $(AM_CFLAGS)
module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c
module_rtp_recv_la_LDFLAGS = -module -avoid-version
-module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore.la librtp.la
+module_rtp_recv_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_rtp_recv_la_CFLAGS = $(AM_CFLAGS)
# JACK
module_jack_sink_la_SOURCES = modules/module-jack-sink.c
module_jack_sink_la_LDFLAGS = -module -avoid-version
-module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS)
+module_jack_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_jack_sink_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
module_jack_source_la_SOURCES = modules/module-jack-source.c
module_jack_source_la_LDFLAGS = -module -avoid-version
-module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore.la $(JACK_LIBS)
+module_jack_source_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la $(JACK_LIBS) libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_jack_source_la_CFLAGS = $(AM_CFLAGS) $(JACK_CFLAGS)
# HAL/D-Bus
libdbus_util_la_SOURCES = modules/dbus-util.c modules/dbus-util.h
libdbus_util_la_LDFLAGS = -avoid-version
-libdbus_util_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore.la
+libdbus_util_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
libdbus_util_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
module_hal_detect_la_SOURCES = modules/module-hal-detect.c
module_hal_detect_la_LDFLAGS = -module -avoid-version
-module_hal_detect_la_LIBADD = $(AM_LIBADD) $(HAL_LIBS) libpulsecore.la libdbus-util.la
+module_hal_detect_la_LIBADD = $(AM_LIBADD) $(HAL_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_hal_detect_la_CFLAGS = $(AM_CFLAGS) $(HAL_CFLAGS)
module_console_kit_la_SOURCES = modules/module-console-kit.c
module_console_kit_la_LDFLAGS = -module -avoid-version
-module_console_kit_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore.la libdbus-util.la
+module_console_kit_la_LIBADD = $(AM_LIBADD) $(DBUS_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_console_kit_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
# GConf support
module_gconf_la_SOURCES = modules/gconf/module-gconf.c
module_gconf_la_LDFLAGS = -module -avoid-version
-module_gconf_la_LIBADD = $(AM_LIBADD) libpulsecore.la
+module_gconf_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
module_gconf_la_CFLAGS = $(AM_CFLAGS) -DPA_GCONF_HELPER=\"$(pulselibexecdir)/gconf-helper\"
gconf_helper_SOURCES = modules/gconf/gconf-helper.c
-gconf_helper_LDADD = $(AM_LDADD) $(GCONF_LIBS) libpulsecore.la
+gconf_helper_LDADD = $(AM_LDADD) $(GCONF_LIBS) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
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\"
+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-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.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-@PA_MAJORMINORMICRO@.la libdbus-util.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.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) libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+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)libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+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-@PA_MAJORMINORMICRO@.la libdbus-util.la libbluetooth-ipc.la libbluetooth-sbc.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_bluetooth_device_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)
+
+# Apple Airtunes/RAOP
+module_raop_sink_la_SOURCES = modules/module-raop-sink.c
+module_raop_sink_la_LDFLAGS = -module -avoid-version
+module_raop_sink_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINORMICRO@.la librtp.la libraop.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+
+module_raop_discover_la_SOURCES = modules/module-raop-discover.c
+module_raop_discover_la_LDFLAGS = -module -avoid-version
+module_raop_discover_la_LIBADD = $(AM_LIBADD) $(AVAHI_LIBS) libavahi-wrap.la libpulsecore-@PA_MAJORMINORMICRO@.la libpulsecommon-@PA_MAJORMINORMICRO@.la libpulse.la
+module_raop_discover_la_CFLAGS = $(AM_CFLAGS) $(AVAHI_CFLAGS)
-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)
###################################
# Some minor stuff #
@@ -1598,7 +1446,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
@@ -1615,7 +1463,7 @@ update-ffmpeg:
update-map-file:
( echo "PULSE_0 {" ; \
echo "global:" ; \
- ctags -I PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
+ ctags -I PA_GCC_MALLOC,PA_GCC_ALLOC_SIZE2,PA_GCC_ALLOC_SIZE,PA_GCC_PURE,PA_GCC_CONST,PA_GCC_DEPRECATED,PA_GCC_PRINTF_ATTR -f - --c-kinds=p $(pulseinclude_HEADERS) | awk '/^pa_/ { print $$1 ";" }' | sort ; \
echo "local:" ; \
echo "*;" ; \
echo "};" ) > $(srcdir)/map-file
diff --git a/src/daemon/caps.c b/src/daemon/caps.c
index f7b6658b..b5cbbc63 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>
@@ -59,7 +60,7 @@ void pa_drop_root(void) {
if (uid == 0 || geteuid() != 0)
return;
- pa_log_info(_("Dropping root priviliges."));
+ pa_log_info(_("Dropping root privileges."));
#if defined(HAVE_SETRESUID)
pa_assert_se(setresuid(uid, uid, uid) >= 0);
@@ -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/cmdline.c b/src/daemon/cmdline.c
index fbd6dc32..0bfc8a92 100644
--- a/src/daemon/cmdline.c
+++ b/src/daemon/cmdline.c
@@ -55,6 +55,9 @@ enum {
ARG_MODULE_IDLE_TIME,
ARG_SCACHE_IDLE_TIME,
ARG_LOG_TARGET,
+ ARG_LOG_META,
+ ARG_LOG_TIME,
+ ARG_LOG_BACKTRACE,
ARG_LOAD,
ARG_FILE,
ARG_DL_SEARCH_PATH,
@@ -88,6 +91,9 @@ static const struct option long_options[] = {
{"module-idle-time", 2, 0, ARG_MODULE_IDLE_TIME},
{"scache-idle-time", 2, 0, ARG_SCACHE_IDLE_TIME},
{"log-target", 1, 0, ARG_LOG_TARGET},
+ {"log-meta", 2, 0, ARG_LOG_META},
+ {"log-time", 2, 0, ARG_LOG_TIME},
+ {"log-backtrace", 1, 0, ARG_LOG_BACKTRACE},
{"load", 1, 0, ARG_LOAD},
{"file", 1, 0, ARG_FILE},
{"dl-search-path", 1, 0, ARG_DL_SEARCH_PATH},
@@ -148,6 +154,9 @@ void pa_cmdline_help(const char *argv0) {
" --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"
+ " --log-meta[=BOOL] Include code location in log messages\n"
+ " --log-time[=BOOL] Include timestamps in log messages\n"
+ " --log-backtrace=FRAMES Include a backtrace in log messages\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"
@@ -321,6 +330,24 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d
}
break;
+ case ARG_LOG_TIME:
+ if ((conf->log_time = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+ pa_log(_("--log-time boolean argument"));
+ goto fail;
+ }
+ break;
+
+ case ARG_LOG_META:
+ if ((conf->log_meta = optarg ? pa_parse_boolean(optarg) : TRUE) < 0) {
+ pa_log(_("--log-meta boolean argument"));
+ goto fail;
+ }
+ break;
+
+ case ARG_LOG_BACKTRACE:
+ conf->log_backtrace = (unsigned) atoi(optarg);
+ break;
+
case ARG_EXIT_IDLE_TIME:
conf->exit_idle_time = atoi(optarg);
break;
diff --git a/src/daemon/cpulimit.c b/src/daemon/cpulimit.c
index 42a71f7e..a909600e 100644
--- a/src/daemon/cpulimit.c
+++ b/src/daemon/cpulimit.c
@@ -24,11 +24,13 @@
#endif
#include <pulse/error.h>
+#include <pulse/timeval.h>
#include <pulsecore/core-util.h>
#include <pulsecore/core-error.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
+#include <pulsecore/rtclock.h>
#include "cpulimit.h"
@@ -67,7 +69,7 @@
#define CPUTIME_INTERVAL_HARD (5)
/* Time of the last CPU load check */
-static time_t last_time = 0;
+static pa_usec_t last_time = 0;
/* Pipe for communicating with the main loop */
static int the_pipe[2] = {-1, -1};
@@ -100,7 +102,7 @@ static void reset_cpu_time(int t) {
n = ru.ru_utime.tv_sec + ru.ru_stime.tv_sec + t;
pa_assert_se(getrlimit(RLIMIT_CPU, &rl) >= 0);
- rl.rlim_cur = n;
+ rl.rlim_cur = (rlim_t) n;
pa_assert_se(setrlimit(RLIMIT_CPU, &rl) >= 0);
}
@@ -117,20 +119,21 @@ static void signal_handler(int sig) {
pa_assert(sig == SIGXCPU);
if (phase == PHASE_IDLE) {
- time_t now;
+ pa_usec_t now, elapsed;
#ifdef PRINT_CPU_LOAD
char t[256];
#endif
- time(&now);
+ now = pa_rtclock_usec();
+ elapsed = now - last_time;
#ifdef PRINT_CPU_LOAD
- pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", (double)CPUTIME_INTERVAL_SOFT/(now-last_time)*100);
+ pa_snprintf(t, sizeof(t), "Using %0.1f%% CPU\n", ((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) / (double) elapsed * 100.0);
write_err(t);
#endif
- if (CPUTIME_INTERVAL_SOFT >= ((now-last_time)*(double)CPUTIME_PERCENT/100)) {
+ if (((double) CPUTIME_INTERVAL_SOFT * (double) PA_USEC_PER_SEC) >= ((double) elapsed * (double) CPUTIME_PERCENT / 100.0)) {
static const char c = 'X';
write_err("Soft CPU time limit exhausted, terminating.\n");
@@ -164,6 +167,8 @@ static void callback(pa_mainloop_api*m, pa_io_event*e, int fd, pa_io_event_flags
pa_assert(e == io_event);
pa_assert(fd == the_pipe[0]);
+ pa_log("Recevied request to terminate due to CPU overload.");
+
pa_read(the_pipe[0], &c, sizeof(c), NULL);
m->quit(m, 1); /* Quit the main loop */
}
@@ -179,7 +184,7 @@ int pa_cpu_limit_init(pa_mainloop_api *m) {
pa_assert(the_pipe[1] == -1);
pa_assert(!installed);
- time(&last_time);
+ last_time = pa_rtclock_usec();
/* Prepare the main loop pipe */
if (pipe(the_pipe) < 0) {
@@ -235,7 +240,7 @@ void pa_cpu_limit_done(void) {
#else /* HAVE_SIGXCPU */
-int pa_cpu_limit_init(PA_GCC_UNUSED pa_mainloop_api *m) {
+int pa_cpu_limit_init(pa_mainloop_api *m) {
return 0;
}
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 05c86c87..d7ffc105 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -74,8 +74,12 @@ static const pa_daemon_conf default_conf = {
.default_script_file = NULL,
.log_target = PA_LOG_SYSLOG,
.log_level = PA_LOG_NOTICE,
+ .log_backtrace = 0,
+ .log_meta = FALSE,
+ .log_time = FALSE,
.resample_method = PA_RESAMPLER_AUTO,
.disable_remixing = FALSE,
+ .disable_lfe_remixing = TRUE,
.config_file = NULL,
.use_pid_file = TRUE,
.system_instance = FALSE,
@@ -83,7 +87,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 },
@@ -191,7 +196,7 @@ int pa_daemon_conf_set_resample_method(pa_daemon_conf *c, const char *string) {
return 0;
}
-static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_log_target(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_assert(filename);
@@ -207,7 +212,7 @@ static int parse_log_target(const char *filename, unsigned line, const char *lva
return 0;
}
-static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_log_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_assert(filename);
@@ -223,7 +228,7 @@ static int parse_log_level(const char *filename, unsigned line, const char *lval
return 0;
}
-static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_resample_method(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_assert(filename);
@@ -239,7 +244,7 @@ static int parse_resample_method(const char *filename, unsigned line, const char
return 0;
}
-static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_rlimit(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
#ifdef HAVE_SYS_RESOURCE_H
struct pa_rlimit *r = data;
@@ -268,7 +273,7 @@ static int parse_rlimit(const char *filename, unsigned line, const char *lvalue,
return 0;
}
-static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_sample_format(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
pa_sample_format_t f;
@@ -286,16 +291,16 @@ static int parse_sample_format(const char *filename, unsigned line, const char *
return 0;
}
-static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_sample_rate(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
- int32_t r;
+ uint32_t r;
pa_assert(filename);
pa_assert(lvalue);
pa_assert(rvalue);
pa_assert(data);
- if (pa_atoi(rvalue, &r) < 0 || r > (int32_t) PA_RATE_MAX || r <= 0) {
+ if (pa_atou(rvalue, &r) < 0 || r > (uint32_t) PA_RATE_MAX || r <= 0) {
pa_log(_("[%s:%u] Invalid sample rate '%s'."), filename, line, rvalue);
return -1;
}
@@ -304,7 +309,7 @@ static int parse_sample_rate(const char *filename, unsigned line, const char *lv
return 0;
}
-static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_sample_channels(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
@@ -322,7 +327,7 @@ static int parse_sample_channels(const char *filename, unsigned line, const char
return 0;
}
-static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_fragments(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
@@ -340,7 +345,7 @@ static int parse_fragments(const char *filename, unsigned line, const char *lval
return 0;
}
-static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_fragment_size_msec(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t n;
@@ -358,7 +363,7 @@ static int parse_fragment_size_msec(const char *filename, unsigned line, const c
return 0;
}
-static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_nice_level(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t level;
@@ -376,7 +381,7 @@ static int parse_nice_level(const char *filename, unsigned line, const char *lva
return 0;
}
-static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+static int parse_rtprio(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
pa_daemon_conf *c = data;
int32_t rtprio;
@@ -397,6 +402,7 @@ static int parse_rtprio(const char *filename, unsigned line, const char *lvalue,
int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
int r = -1;
FILE *f = NULL;
+ unsigned i = 0;
pa_config_item table[] = {
{ "daemonize", pa_config_parse_bool, NULL },
@@ -426,7 +432,12 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "default-fragment-size-msec", parse_fragment_size_msec, NULL },
{ "nice-level", parse_nice_level, NULL },
{ "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 },
+ { "log-meta", pa_config_parse_bool, NULL },
+ { "log-time", pa_config_parse_bool, NULL },
+ { "log-backtrace", pa_config_parse_unsigned, NULL },
#ifdef HAVE_SYS_RESOURCE_H
{ "rlimit-fsize", parse_rlimit, NULL },
{ "rlimit-data", parse_rlimit, NULL },
@@ -463,96 +474,75 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ NULL, NULL, NULL },
};
- table[0].data = &c->daemonize;
- table[1].data = &c->fail;
- table[2].data = &c->high_priority;
- table[3].data = &c->realtime_scheduling;
- table[4].data = &c->disallow_module_loading;
- table[5].data = &c->disallow_exit;
- table[6].data = &c->use_pid_file;
- table[7].data = &c->system_instance;
- table[8].data = &c->no_cpu_limit;
- table[9].data = &c->disable_shm;
- table[10].data = &c->exit_idle_time;
- table[11].data = &c->module_idle_time;
- table[12].data = &c->scache_idle_time;
- table[13].data = c;
- table[14].data = &c->dl_search_path;
- table[15].data = &c->default_script_file;
- table[16].data = c;
- table[17].data = c;
- table[18].data = c;
- table[19].data = c;
- table[20].data = c;
- table[21].data = c;
- table[22].data = c;
- table[23].data = c;
- table[24].data = c;
- table[25].data = c;
- table[26].data = &c->disable_remixing;
- table[27].data = &c->load_default_script_file;
+ table[i++].data = &c->daemonize;
+ table[i++].data = &c->fail;
+ table[i++].data = &c->high_priority;
+ table[i++].data = &c->realtime_scheduling;
+ table[i++].data = &c->disallow_module_loading;
+ table[i++].data = &c->disallow_exit;
+ table[i++].data = &c->use_pid_file;
+ table[i++].data = &c->system_instance;
+ table[i++].data = &c->no_cpu_limit;
+ table[i++].data = &c->disable_shm;
+ table[i++].data = &c->exit_idle_time;
+ table[i++].data = &c->module_idle_time;
+ table[i++].data = &c->scache_idle_time;
+ table[i++].data = c;
+ table[i++].data = &c->dl_search_path;
+ table[i++].data = &c->default_script_file;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = c;
+ table[i++].data = &c->disable_remixing;
+ table[i++].data = &c->disable_lfe_remixing;
+ table[i++].data = &c->load_default_script_file;
+ table[i++].data = &c->shm_size;
+ table[i++].data = &c->log_meta;
+ table[i++].data = &c->log_time;
+ table[i++].data = &c->log_backtrace;
#ifdef HAVE_SYS_RESOURCE_H
- table[28].data = &c->rlimit_fsize;
- table[29].data = &c->rlimit_data;
- table[30].data = &c->rlimit_stack;
- table[31].data = &c->rlimit_as;
- table[32].data = &c->rlimit_core;
- table[33].data = &c->rlimit_nofile;
- table[34].data = &c->rlimit_as;
+ table[i++].data = &c->rlimit_fsize;
+ table[i++].data = &c->rlimit_data;
+ table[i++].data = &c->rlimit_stack;
+ table[i++].data = &c->rlimit_as;
+ table[i++].data = &c->rlimit_core;
+ table[i++].data = &c->rlimit_nofile;
+ table[i++].data = &c->rlimit_as;
#ifdef RLIMIT_NPROC
- table[35].data = &c->rlimit_nproc;
+ table[i++].data = &c->rlimit_nproc;
#endif
-
#ifdef RLIMIT_MEMLOCK
-#ifndef RLIMIT_NPROC
-#error "Houston, we have a numbering problem!"
-#endif
- table[36].data = &c->rlimit_memlock;
+ table[i++].data = &c->rlimit_memlock;
#endif
-
#ifdef RLIMIT_LOCKS
-#ifndef RLIMIT_MEMLOCK
-#error "Houston, we have a numbering problem!"
-#endif
- table[37].data = &c->rlimit_locks;
+ table[i++].data = &c->rlimit_locks;
#endif
-
#ifdef RLIMIT_SIGPENDING
-#ifndef RLIMIT_LOCKS
-#error "Houston, we have a numbering problem!"
-#endif
- table[38].data = &c->rlimit_sigpending;
+ table[i++].data = &c->rlimit_sigpending;
#endif
-
#ifdef RLIMIT_MSGQUEUE
-#ifndef RLIMIT_SIGPENDING
-#error "Houston, we have a numbering problem!"
-#endif
- table[39].data = &c->rlimit_msgqueue;
+ table[i++].data = &c->rlimit_msgqueue;
#endif
-
#ifdef RLIMIT_NICE
-#ifndef RLIMIT_MSGQUEUE
-#error "Houston, we have a numbering problem!"
-#endif
- table[40].data = &c->rlimit_nice;
+ table[i++].data = &c->rlimit_nice;
#endif
-
#ifdef RLIMIT_RTPRIO
-#ifndef RLIMIT_NICE
-#error "Houston, we have a numbering problem!"
-#endif
- table[41].data = &c->rlimit_rtprio;
+ table[i++].data = &c->rlimit_rtprio;
#endif
-
#ifdef RLIMIT_RTTIME
-#ifndef RLIMIT_RTTIME
-#error "Houston, we have a numbering problem!"
-#endif
- table[42].data = &c->rlimit_rttime;
+ table[i++].data = &c->rlimit_rttime;
#endif
#endif
+ pa_assert(i == PA_ELEMENTSOF(table)-1);
+
pa_xfree(c->config_file);
c->config_file = NULL;
@@ -661,11 +651,16 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "log-level = %s\n", log_level_to_string[c->log_level]);
pa_strbuf_printf(s, "resample-method = %s\n", pa_resample_method_to_string(c->resample_method));
pa_strbuf_printf(s, "disable-remixing = %s\n", pa_yes_no(c->disable_remixing));
+ pa_strbuf_printf(s, "disable-lfe-remixing = %s\n", pa_yes_no(c->disable_lfe_remixing));
pa_strbuf_printf(s, "default-sample-format = %s\n", pa_sample_format_to_string(c->default_sample_spec.format));
pa_strbuf_printf(s, "default-sample-rate = %u\n", c->default_sample_spec.rate);
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);
+ pa_strbuf_printf(s, "log-meta = %s\n", pa_yes_no(c->log_meta));
+ pa_strbuf_printf(s, "log-time = %s\n", pa_yes_no(c->log_time));
+ pa_strbuf_printf(s, "log-backtrace = %u\n", c->log_backtrace);
#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 c42984f9..04a4ebe7 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -66,8 +66,11 @@ typedef struct pa_daemon_conf {
no_cpu_limit,
disable_shm,
disable_remixing,
+ disable_lfe_remixing,
load_default_script_file,
- disallow_exit;
+ disallow_exit,
+ log_meta,
+ log_time;
int exit_idle_time,
module_idle_time,
scache_idle_time,
@@ -78,6 +81,7 @@ typedef struct pa_daemon_conf {
char *script_commands, *dl_search_path, *default_script_file;
pa_log_target_t log_target;
pa_log_level_t log_level;
+ unsigned log_backtrace;
char *config_file;
#ifdef HAVE_SYS_RESOURCE_H
@@ -110,6 +114,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 33b1d61d..00a95932 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,14 +40,18 @@
; 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
; log-level = notice
+; log-meta = no
+; log-time = no
+; log-backtrace = 0
; resample-method = speex-float-3
; disable-remixing = no
+; disable-lfe-remixing = yes
; no-cpu-limit = no
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index cdaa8bbd..a8318766 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -23,7 +23,7 @@
### Load something into the sample cache
#load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav
-load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
+#load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav
#load-sample-lazy pulse-access /usr/share/sounds/generic.wav
@@ -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
@@ -67,9 +72,12 @@ load-module module-native-protocol-unix
#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 description="RTP Multicast Sink"
#load-module module-rtp-send source=rtp.monitor
+### Enable flat volumes where possible
+load-module module-flat-volume
+
### Automatically restore the volume of streams and devices
-load-module module-stream-restore
load-module module-device-restore
+load-module module-stream-restore
### Automatically restore the default sink/source when changed by the user during runtime
load-module module-default-device-restore
diff --git a/src/daemon/dumpmodules.c b/src/daemon/dumpmodules.c
index 26fb8eef..9c9f1c81 100644
--- a/src/daemon/dumpmodules.c
+++ b/src/daemon/dumpmodules.c
@@ -40,7 +40,7 @@
#define PREFIX "module-"
-static void short_info(const char *name, PA_GCC_UNUSED const char *path, pa_modinfo *i) {
+static void short_info(const char *name, const char *path, pa_modinfo *i) {
pa_assert(name);
pa_assert(i);
diff --git a/src/daemon/ltdl-bind-now.c b/src/daemon/ltdl-bind-now.c
index 6821aac4..2d80fc7a 100644
--- a/src/daemon/ltdl-bind-now.c
+++ b/src/daemon/ltdl-bind-now.c
@@ -24,11 +24,11 @@
#include <config.h>
#endif
-#if HAVE_DLFCN_H
+#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
-#if HAVE_SYS_DL_H
+#ifdef HAVE_SYS_DL_H
#include <sys/dl.h>
#endif
@@ -74,7 +74,9 @@ static lt_module bind_now_open(lt_user_data d, const char *fname, lt_dladvise ad
pa_assert(fname);
if (!(m = dlopen(fname, PA_BIND_NOW))) {
+#ifdef HAVE_LT_DLMUTEX_REGISTER
libtool_set_error(dlerror());
+#endif
return NULL;
}
@@ -86,7 +88,9 @@ static int bind_now_close(lt_user_data d, lt_module m) {
pa_assert(m);
if (dlclose(m) != 0){
+#ifdef HAVE_LT_DLMUTEX_REGISTER
libtool_set_error(dlerror());
+#endif
return 1;
}
@@ -100,7 +104,9 @@ static lt_ptr bind_now_find_sym(lt_user_data d, lt_module m, const char *symbol)
pa_assert(symbol);
if (!(ptr = dlsym(m, symbol))) {
+#ifdef HAVE_LT_DLMUTEX_REGISTER
libtool_set_error(dlerror());
+#endif
return NULL;
}
diff --git a/src/daemon/main.c b/src/daemon/main.c
index ab438320..f6d2512c 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -66,6 +66,7 @@
#include <pulse/xmalloc.h>
#include <pulse/i18n.h>
+#include <pulsecore/lock-autospawn.h>
#include <pulsecore/winsock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/core.h>
@@ -95,8 +96,6 @@
#include "ltdl-bind-now.h"
#include "polkit.h"
-#define AUTOSPAWN_LOCK "autospawn.lock"
-
#ifdef HAVE_LIBWRAP
/* Only one instance of these variables */
int allow_severity = LOG_INFO;
@@ -112,7 +111,7 @@ int __padsp_disabled__ = 7;
#ifdef OS_IS_WIN32
-static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
+static void message_cb(pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata) {
MSG msg;
struct timeval tvnext;
@@ -131,7 +130,7 @@ static void message_cb(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const s
#endif
-static void signal_callback(pa_mainloop_api*m, PA_GCC_UNUSED pa_signal_event *e, int sig, void *userdata) {
+static void signal_callback(pa_mainloop_api*m, pa_signal_event *e, int sig, void *userdata) {
pa_log_info(_("Got signal %s."), pa_sig2str(sig));
switch (sig) {
@@ -223,7 +222,7 @@ static int change_user(void) {
#elif defined(HAVE_SETREGID)
r = setregid(gr->gr_gid, gr->gr_gid);
#else
-#error "No API to drop priviliges"
+#error "No API to drop privileges"
#endif
if (r < 0) {
@@ -239,7 +238,7 @@ static int change_user(void) {
#elif defined(HAVE_SETREUID)
r = setreuid(pw->pw_uid, pw->pw_uid);
#else
-#error "No API to drop priviliges"
+#error "No API to drop privileges"
#endif
if (r < 0) {
@@ -346,7 +345,11 @@ int main(int argc, char *argv[]) {
struct timeval win32_tv;
#endif
char *lf = NULL;
- int autospawn_lock_fd = -1;
+ int autospawn_fd = -1;
+ pa_bool_t autospawn_locked = FALSE;
+
+ pa_log_set_maximal_level(PA_LOG_INFO);
+ pa_log_set_ident("pulseaudio");
#if defined(__linux__) && defined(__OPTIMIZE__)
/*
@@ -379,7 +382,7 @@ int main(int argc, char *argv[]) {
/* Drop all capabilities except CAP_SYS_NICE */
pa_limit_caps();
- /* Drop priviliges, but keep CAP_SYS_NICE */
+ /* Drop privileges, but keep CAP_SYS_NICE */
pa_drop_root();
/* After dropping root, the effective set is reset, hence,
@@ -410,9 +413,6 @@ int main(int argc, char *argv[]) {
setlocale(LC_ALL, "");
pa_init_i18n();
- pa_log_set_maximal_level(PA_LOG_INFO);
- pa_log_set_ident("pulseaudio");
-
conf = pa_daemon_conf_new();
if (pa_daemon_conf_load(conf, NULL) < 0)
@@ -428,6 +428,9 @@ int main(int argc, char *argv[]) {
pa_log_set_maximal_level(conf->log_level);
pa_log_set_target(conf->auto_log_target ? PA_LOG_STDERR : conf->log_target, NULL);
+ pa_log_set_show_meta(conf->log_meta);
+ pa_log_set_show_backtrace(conf->log_backtrace);
+ pa_log_set_show_time(conf->log_time);
pa_log_debug("Started as real root: %s, suid root: %s", pa_yes_no(real_root), pa_yes_no(suid_root));
@@ -476,9 +479,9 @@ int main(int argc, char *argv[]) {
pa_drop_caps();
if (conf->high_priority || conf->realtime_scheduling)
- pa_log_notice(_("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 '"PA_REALTIME_GROUP"' 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 '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."));
+ pa_log_notice(_("Called SUID root and real-time/high-priority scheduling was requested in the configuration. However, we lack the necessary privileges:\n"
+ "We are not in group '"PA_REALTIME_GROUP"' and PolicyKit refuse to grant us privileges. Dropping SUID again.\n"
+ "For enabling real-time scheduling please acquire the appropriate PolicyKit privileges, or become a member of '"PA_REALTIME_GROUP"', or increase the RLIMIT_NICE/RLIMIT_RTPRIO resource limits for this user."));
}
}
@@ -606,7 +609,7 @@ int main(int argc, char *argv[]) {
case PA_CMD_KILL:
if (pa_pid_file_kill(SIGINT, NULL, "pulseaudio") < 0)
- pa_log(_("Failed to kill daemon."));
+ pa_log(_("Failed to kill daemon: %s"), pa_cstrerror(errno));
else
retval = 0;
@@ -626,7 +629,7 @@ int main(int argc, char *argv[]) {
if (real_root && !conf->system_instance)
pa_log_warn(_("This program is not intended to be run as root (unless --system is specified)."));
else if (!real_root && conf->system_instance) {
- pa_log(_("Root priviliges required."));
+ pa_log(_("Root privileges required."));
goto finish;
}
@@ -646,9 +649,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) {
@@ -656,8 +659,17 @@ int main(int argc, char *argv[]) {
* first take the autospawn lock to make things
* synchronous. */
- lf = pa_runtime_path(AUTOSPAWN_LOCK);
- autospawn_lock_fd = pa_lock_lockfile(lf);
+ if ((autospawn_fd = pa_autospawn_lock_init()) < 0) {
+ pa_log("Failed to initialize autospawn lock");
+ goto finish;
+ }
+
+ if ((pa_autospawn_lock_acquire(TRUE) < 0)) {
+ pa_log("Failed to acquire autospawn lock");
+ goto finish;
+ }
+
+ autospawn_locked = TRUE;
}
if (conf->daemonize) {
@@ -703,12 +715,15 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (autospawn_lock_fd >= 0) {
+ if (autospawn_fd >= 0) {
/* The lock file is unlocked from the parent, so we need
* to close it in the child */
- pa_close(autospawn_lock_fd);
- autospawn_lock_fd = -1;
+ pa_autospawn_lock_release();
+ pa_autospawn_lock_done(TRUE);
+
+ autospawn_locked = FALSE;
+ autospawn_fd = -1;
}
pa_assert_se(pa_close(daemon_pipe[0]) == 0);
@@ -766,8 +781,29 @@ int main(int argc, char *argv[]) {
pa_set_env("PULSE_SYSTEM", conf->system_instance ? "1" : "0");
pa_log_info(_("This is PulseAudio %s"), PACKAGE_VERSION);
+ pa_log_debug(_("Compilation host: %s"), CANONICAL_HOST);
+ pa_log_debug(_("Compilation CFLAGS: %s"), PA_CFLAGS);
+
+ s = pa_uname_string();
+ pa_log_debug(_("Running on host: %s"), s);
+ pa_xfree(s);
+
pa_log_info(_("Page size is %lu bytes"), (unsigned long) PA_PAGE_SIZE);
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ pa_log_debug(_("Compiled with Valgrind support: yes"));
+#else
+ 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
+ pa_log_debug(_("Optimized build: no"));
+#endif
+
if (!(s = pa_machine_id())) {
pa_log(_("Failed to get machine ID"));
goto finish;
@@ -823,7 +859,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;
}
@@ -838,6 +874,7 @@ int main(int argc, char *argv[]) {
c->realtime_priority = conf->realtime_priority;
c->realtime_scheduling = !!conf->realtime_scheduling;
c->disable_remixing = !!conf->disable_remixing;
+ c->disable_lfe_remixing = !!conf->disable_lfe_remixing;
c->running_as_daemon = !!conf->daemonize;
c->disallow_exit = conf->disallow_exit;
@@ -917,8 +954,12 @@ int main(int argc, char *argv[]) {
finish:
- if (autospawn_lock_fd >= 0)
- pa_unlock_lockfile(lf, autospawn_lock_fd);
+ if (autospawn_fd >= 0) {
+ if (autospawn_locked)
+ pa_autospawn_lock_release();
+
+ pa_autospawn_lock_done(FALSE);
+ }
if (lf)
pa_xfree(lf);
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 b6d3b63d..ca523b91 100644
--- a/src/map-file
+++ b/src/map-file
@@ -9,6 +9,7 @@ pa_browser_unref;
pa_bytes_per_second;
pa_bytes_snprint;
pa_bytes_to_usec;
+pa_channel_map_compatible;
pa_channel_map_equal;
pa_channel_map_init;
pa_channel_map_init_auto;
@@ -97,7 +98,10 @@ 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;
@@ -158,6 +162,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;
@@ -222,7 +227,10 @@ pa_stream_update_timing_info;
pa_stream_writable_size;
pa_stream_write;
pa_strerror;
+pa_sw_cvolume_divide;
pa_sw_cvolume_multiply;
+pa_sw_cvolume_snprint_dB;
+pa_sw_volume_divide;
pa_sw_volume_from_dB;
pa_sw_volume_from_linear;
pa_sw_volume_multiply;
diff --git a/src/modules/alsa-util.c b/src/modules/alsa-util.c
index 8abf834d..20dc400f 100644
--- a/src/modules/alsa-util.c
+++ b/src/modules/alsa-util.c
@@ -30,6 +30,7 @@
#include <pulse/sample.h>
#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
@@ -39,7 +40,7 @@
#include "alsa-util.h"
struct pa_alsa_fdlist {
- int num_fds;
+ unsigned num_fds;
struct pollfd *fds;
/* This is a temporary buffer used to avoid lots of mallocs */
struct pollfd *work_fds;
@@ -50,16 +51,17 @@ struct pa_alsa_fdlist {
pa_defer_event *defer;
pa_io_event **ios;
- int polled;
+ pa_bool_t polled;
void (*cb)(void *userdata);
void *userdata;
};
-static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void *userdata) {
+static void io_cb(pa_mainloop_api*a, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata) {
struct pa_alsa_fdlist *fdl = userdata;
- int err, i;
+ int err;
+ unsigned i;
unsigned short revents;
pa_assert(a);
@@ -71,11 +73,11 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io
if (fdl->polled)
return;
- fdl->polled = 1;
+ fdl->polled = TRUE;
memcpy(fdl->work_fds, fdl->fds, sizeof(struct pollfd) * fdl->num_fds);
- for (i = 0;i < fdl->num_fds; i++) {
+ for (i = 0; i < fdl->num_fds; i++) {
if (e == fdl->ios[i]) {
if (events & PA_IO_EVENT_INPUT)
fdl->work_fds[i].revents |= POLLIN;
@@ -102,9 +104,10 @@ static void io_cb(pa_mainloop_api*a, pa_io_event* e, PA_GCC_UNUSED int fd, pa_io
snd_mixer_handle_events(fdl->mixer);
}
-static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *userdata) {
+static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
struct pa_alsa_fdlist *fdl = userdata;
- int num_fds, i, err;
+ unsigned num_fds, i;
+ int err;
struct pollfd *temp;
pa_assert(a);
@@ -113,8 +116,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u
a->defer_enable(fdl->defer, 0);
- num_fds = snd_mixer_poll_descriptors_count(fdl->mixer);
- pa_assert(num_fds > 0);
+ num_fds = (unsigned) snd_mixer_poll_descriptors_count(fdl->mixer);
if (num_fds != fdl->num_fds) {
if (fdl->fds)
@@ -132,7 +134,7 @@ static void defer_cb(pa_mainloop_api*a, PA_GCC_UNUSED pa_defer_event* e, void *u
return;
}
- fdl->polled = 0;
+ fdl->polled = FALSE;
if (memcmp(fdl->fds, fdl->work_fds, sizeof(struct pollfd) * num_fds) == 0)
return;
@@ -176,7 +178,7 @@ struct pa_alsa_fdlist *pa_alsa_fdlist_new(void) {
fdl->m = NULL;
fdl->defer = NULL;
fdl->ios = NULL;
- fdl->polled = 0;
+ fdl->polled = FALSE;
return fdl;
}
@@ -190,9 +192,9 @@ void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl) {
}
if (fdl->ios) {
- int i;
+ unsigned i;
pa_assert(fdl->m);
- for (i = 0;i < fdl->num_fds;i++)
+ for (i = 0; i < fdl->num_fds; i++)
fdl->m->io_free(fdl->ios[i]);
pa_xfree(fdl->ios);
}
@@ -369,11 +371,18 @@ int pa_alsa_set_hw_params(
goto finish;
if (_periods > 0) {
- dir = 1;
+
+ /* First we pass 0 as direction to get exactly what we asked
+ * for. That this is necessary is presumably a bug in ALSA */
+
+ dir = 0;
if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0) {
- dir = -1;
- if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0)
- goto finish;
+ dir = 1;
+ if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0) {
+ dir = -1;
+ if ((ret = snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &_periods, &dir)) < 0)
+ goto finish;
+ }
}
}
@@ -403,7 +412,7 @@ int pa_alsa_set_hw_params(
/* If the sample rate deviates too much, we need to resample */
if (r < ss->rate*.95 || r > ss->rate*1.05)
ss->rate = r;
- ss->channels = c;
+ ss->channels = (uint8_t) c;
ss->format = f;
pa_assert(_periods > 0);
@@ -420,6 +429,8 @@ int pa_alsa_set_hw_params(
ret = 0;
+ snd_pcm_nonblock(pcm_handle, 1);
+
finish:
return ret;
@@ -568,40 +579,60 @@ snd_pcm_t *pa_alsa_open_by_device_id(
continue;
d = pa_sprintf_malloc("%s:%s", device_table[i].name, dev_id);
- pa_log_debug("Trying %s...", d);
- if ((err = snd_pcm_open(&pcm_handle, d, mode,
- SND_PCM_NONBLOCK|
- SND_PCM_NO_AUTO_RESAMPLE|
- SND_PCM_NO_AUTO_CHANNELS|
- SND_PCM_NO_AUTO_FORMAT |
- SND_PCM_NO_SOFTVOL)) < 0) {
- pa_log_info("Couldn't open PCM device %s: %s", d, snd_strerror(err));
- pa_xfree(d);
- continue;
- }
+ for (;;) {
+ pa_log_debug("Trying %s...", d);
+
+ /* We don't pass SND_PCM_NONBLOCK here, since alsa-lib <=
+ * 1.0.17a would then ignore the SND_PCM_NO_xxx
+ * flags. Instead we enable nonblock mode afterwards via
+ * snd_pcm_nonblock(). Also see
+ * http://mailman.alsa-project.org/pipermail/alsa-devel/2008-August/010258.html */
+
+ if ((err = snd_pcm_open(&pcm_handle, d, mode,
+ /* SND_PCM_NONBLOCK| */
+ SND_PCM_NO_AUTO_RESAMPLE|
+ SND_PCM_NO_AUTO_CHANNELS|
+ SND_PCM_NO_AUTO_FORMAT)) < 0) {
+ pa_log_info("Couldn't open PCM device %s: %s", d, snd_strerror(err));
+ break;
+ }
- try_ss.channels = device_table[i].map.channels;
- try_ss.rate = ss->rate;
- try_ss.format = ss->format;
+ try_ss.channels = device_table[i].map.channels;
+ try_ss.rate = ss->rate;
+ try_ss.format = ss->format;
- if ((err = pa_alsa_set_hw_params(pcm_handle, &try_ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, TRUE)) < 0) {
- pa_log_info("PCM device %s refused our hw parameters: %s", d, snd_strerror(err));
- pa_xfree(d);
- snd_pcm_close(pcm_handle);
- continue;
+ if ((err = pa_alsa_set_hw_params(pcm_handle, &try_ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, TRUE)) < 0) {
+
+ if (!pa_startswith(d, "plug:") && !pa_startswith(d, "plughw:")) {
+ char *t;
+
+ t = pa_sprintf_malloc("plug:%s", d);
+ pa_xfree(d);
+ d = t;
+
+ snd_pcm_close(pcm_handle);
+ continue;
+ }
+
+ pa_log_info("PCM device %s refused our hw parameters: %s", d, snd_strerror(err));
+ snd_pcm_close(pcm_handle);
+ break;
+ }
+
+ *ss = try_ss;
+ *map = device_table[i].map;
+ pa_assert(map->channels == ss->channels);
+ *dev = d;
+ return pcm_handle;
}
- *ss = try_ss;
- *map = device_table[i].map;
- pa_assert(map->channels == ss->channels);
- *dev = d;
- return pcm_handle;
+ pa_xfree(d);
}
/* OK, we didn't find any good device, so let's try the raw plughw: stuff */
- d = pa_sprintf_malloc("plughw:%s", dev_id);
+ d = pa_sprintf_malloc("hw:%s", dev_id);
pa_log_debug("Trying %s as last resort...", d);
pcm_handle = pa_alsa_open_by_device_string(d, dev, ss, map, mode, nfrags, period_size, tsched_size, use_mmap, use_tsched);
pa_xfree(d);
@@ -635,8 +666,16 @@ snd_pcm_t *pa_alsa_open_by_device_string(
d = pa_xstrdup(device);
for (;;) {
+ pa_log_debug("Trying %s...", d);
+
+ /* We don't pass SND_PCM_NONBLOCK here, since alsa-lib <=
+ * 1.0.17a would then ignore the SND_PCM_NO_xxx flags. Instead
+ * we enable nonblock mode afterwards via
+ * snd_pcm_nonblock(). Also see
+ * http://mailman.alsa-project.org/pipermail/alsa-devel/2008-August/010258.html */
- if ((err = snd_pcm_open(&pcm_handle, d, mode, SND_PCM_NONBLOCK|
+ if ((err = snd_pcm_open(&pcm_handle, d, mode,
+ /*SND_PCM_NONBLOCK|*/
SND_PCM_NO_AUTO_RESAMPLE|
SND_PCM_NO_AUTO_CHANNELS|
SND_PCM_NO_AUTO_FORMAT)) < 0) {
@@ -647,24 +686,23 @@ snd_pcm_t *pa_alsa_open_by_device_string(
if ((err = pa_alsa_set_hw_params(pcm_handle, ss, nfrags, period_size, tsched_size, use_mmap, use_tsched, FALSE)) < 0) {
- if (err == -EPERM) {
- /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */
+ /* Hmm, some hw is very exotic, so we retry with plug, if without it didn't work */
- if (pa_startswith(d, "hw:")) {
- char *t = pa_sprintf_malloc("plughw:%s", d+3);
- pa_log_debug("Opening the device as '%s' didn't work, retrying with '%s'.", d, t);
- pa_xfree(d);
- d = t;
+ if (!pa_startswith(d, "plug:") && !pa_startswith(d, "plughw:")) {
+ char *t;
- snd_pcm_close(pcm_handle);
- continue;
- }
-
- pa_log("Failed to set hardware parameters on %s: %s", d, snd_strerror(err));
+ t = pa_sprintf_malloc("plug:%s", d);
pa_xfree(d);
+ d = t;
+
snd_pcm_close(pcm_handle);
- return NULL;
+ continue;
}
+
+ pa_log("Failed to set hardware parameters on %s: %s", d, snd_strerror(err));
+ pa_xfree(d);
+ snd_pcm_close(pcm_handle);
+ return NULL;
}
*dev = d;
@@ -808,7 +846,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
if (channel_map->channels > 1 &&
((playback && snd_mixer_selem_has_playback_volume_joined(elem)) ||
(!playback && snd_mixer_selem_has_capture_volume_joined(elem)))) {
- pa_log_info("ALSA device lacks independant volume controls for each channel, falling back to software volume control.");
+ pa_log_info("ALSA device lacks independant volume controls for each channel.");
return -1;
}
@@ -820,7 +858,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
id = alsa_channel_ids[channel_map->map[i]];
if (!is_mono && id == SND_MIXER_SCHN_UNKNOWN) {
- pa_log_info("Configured channel map contains channel '%s' that is unknown to the ALSA mixer. Falling back to software volume control.", pa_channel_position_to_string(channel_map->map[i]));
+ pa_log_info("Configured channel map contains channel '%s' that is unknown to the ALSA mixer.", pa_channel_position_to_string(channel_map->map[i]));
return -1;
}
@@ -832,7 +870,7 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
if ((playback && (!snd_mixer_selem_has_playback_channel(elem, id) || (is_mono && !snd_mixer_selem_is_playback_mono(elem)))) ||
(!playback && (!snd_mixer_selem_has_capture_channel(elem, id) || (is_mono && !snd_mixer_selem_is_capture_mono(elem))))) {
- pa_log_info("ALSA device lacks separate volumes control for channel '%s', falling back to software volume control.", pa_channel_position_to_string(channel_map->map[i]));
+ pa_log_info("ALSA device lacks separate volumes control for channel '%s'", pa_channel_position_to_string(channel_map->map[i]));
return -1;
}
@@ -850,56 +888,6 @@ int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel
return 0;
}
-void pa_alsa_0dB_playback(snd_mixer_elem_t *elem) {
- long min, max, v;
-
- pa_assert(elem);
-
- /* Try to enable 0 dB if possible. If ALSA cannot do dB, then use
- * raw volume levels and fix them to 75% */
-
- if (snd_mixer_selem_set_playback_dB_all(elem, 0, -1) >= 0)
- return;
-
- if (snd_mixer_selem_set_playback_dB_all(elem, 0, 1) >= 0)
- return;
-
- if (snd_mixer_selem_get_playback_volume_range(elem, &min, &max) < 0)
- return;
-
- v = min + ((max - min) * 3) / 4; /* 75% */
-
- if (v <= min)
- v = max;
-
- snd_mixer_selem_set_playback_volume_all(elem, v);
-}
-
-void pa_alsa_0dB_capture(snd_mixer_elem_t *elem) {
- long min, max, v;
-
- pa_assert(elem);
-
- /* Try to enable 0 dB if possible. If ALSA cannot do dB, then use
- * raw volume levels and fix them to 75% */
-
- if (snd_mixer_selem_set_capture_dB_all(elem, 0, -1) >= 0)
- return;
-
- if (snd_mixer_selem_set_capture_dB_all(elem, 0, 1) >= 0)
- return;
-
- if (snd_mixer_selem_get_capture_volume_range(elem, &min, &max) < 0)
- return;
-
- v = min + ((max - min) * 3) / 4; /* 75% */
-
- if (v <= min)
- v = max;
-
- snd_mixer_selem_set_capture_volume_all(elem, v);
-}
-
void pa_alsa_dump(snd_pcm_t *pcm) {
int err;
snd_output_t *out;
@@ -945,12 +933,17 @@ void pa_alsa_dump_status(snd_pcm_t *pcm) {
static void alsa_error_handler(const char *file, int line, const char *function, int err, const char *fmt,...) {
va_list ap;
+ char *alsa_file;
+
+ alsa_file = pa_sprintf_malloc("(alsa-lib)%s", file);
va_start(ap, fmt);
- pa_log_levelv_meta(PA_LOG_WARN, file, line, function, fmt, ap);
+ pa_log_levelv_meta(PA_LOG_INFO, alsa_file, line, function, fmt, ap);
va_end(ap);
+
+ pa_xfree(alsa_file);
}
static pa_atomic_t n_error_handler_installed = PA_ATOMIC_INIT(0);
@@ -1058,6 +1051,12 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
pa_log_warn("Got POLLNVAL from ALSA");
if (revents & POLLHUP)
pa_log_warn("Got POLLHUP from ALSA");
+ if (revents & POLLPRI)
+ pa_log_warn("Got POLLPRI from ALSA");
+ if (revents & POLLIN)
+ pa_log_warn("Got POLLIN from ALSA");
+ if (revents & POLLOUT)
+ pa_log_warn("Got POLLOUT from ALSA");
state = snd_pcm_state(pcm);
pa_log_warn("PCM state is %s", snd_pcm_state_name(state));
@@ -1106,10 +1105,10 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
return NULL;
}
- item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, n);
+ item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_NEVER, (unsigned) n);
pollfd = pa_rtpoll_item_get_pollfd(item, NULL);
- if ((err = snd_pcm_poll_descriptors(pcm, pollfd, n)) < 0) {
+ if ((err = snd_pcm_poll_descriptors(pcm, pollfd, (unsigned) n)) < 0) {
pa_log("snd_pcm_poll_descriptors() failed: %s", snd_strerror(err));
pa_rtpoll_item_free(item);
return NULL;
@@ -1117,3 +1116,62 @@ pa_rtpoll_item* pa_alsa_build_pollfd(snd_pcm_t *pcm, pa_rtpoll *rtpoll) {
return item;
}
+
+snd_pcm_sframes_t pa_alsa_safe_avail_update(snd_pcm_t *pcm, size_t hwbuf_size, const pa_sample_spec *ss) {
+ snd_pcm_sframes_t n;
+ size_t k;
+
+ pa_assert(pcm);
+ pa_assert(hwbuf_size > 0);
+ pa_assert(ss);
+
+ /* Some ALSA driver expose weird bugs, let's inform the user about
+ * what is going on */
+
+ n = snd_pcm_avail_update(pcm);
+
+ if (n <= 0)
+ return n;
+
+ k = (size_t) n * pa_frame_size(ss);
+
+ if (k >= hwbuf_size * 3 ||
+ k >= pa_bytes_per_second(ss)*10)
+ pa_log("snd_pcm_avail_update() returned a value that is exceptionally large: %lu bytes (%lu ms) "
+ "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.",
+ (unsigned long) k, (unsigned long) pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC);
+
+ return n;
+}
+
+int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames, size_t hwbuf_size, const pa_sample_spec *ss) {
+ int r;
+ snd_pcm_uframes_t before;
+ size_t k;
+
+ pa_assert(pcm);
+ pa_assert(areas);
+ pa_assert(offset);
+ pa_assert(frames);
+ pa_assert(hwbuf_size > 0);
+ pa_assert(ss);
+
+ before = *frames;
+
+ r = snd_pcm_mmap_begin(pcm, areas, offset, frames);
+
+ if (r < 0)
+ return r;
+
+ k = (size_t) *frames * pa_frame_size(ss);
+
+ if (*frames > before ||
+ k >= hwbuf_size * 3 ||
+ k >= pa_bytes_per_second(ss)*10)
+
+ pa_log("snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes (%lu ms) "
+ "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.",
+ (unsigned long) k, (unsigned long) pa_bytes_to_usec(k, ss) / PA_USEC_PER_MSEC);
+
+ return r;
+}
diff --git a/src/modules/alsa-util.h b/src/modules/alsa-util.h
index 4de8bcd2..aaa01c78 100644
--- a/src/modules/alsa-util.h
+++ b/src/modules/alsa-util.h
@@ -26,6 +26,7 @@
#include <asoundlib.h>
#include <pulse/sample.h>
+#include <pulse/volume.h>
#include <pulse/mainloop-api.h>
#include <pulse/channelmap.h>
#include <pulse/proplist.h>
@@ -79,9 +80,6 @@ snd_pcm_t *pa_alsa_open_by_device_string(
int pa_alsa_calc_mixer_map(snd_mixer_elem_t *elem, const pa_channel_map *channel_map, snd_mixer_selem_channel_id_t mixer_map[], pa_bool_t playback);
-void pa_alsa_0dB_playback(snd_mixer_elem_t *elem);
-void pa_alsa_0dB_capture(snd_mixer_elem_t *elem);
-
void pa_alsa_dump(snd_pcm_t *pcm);
void pa_alsa_dump_status(snd_pcm_t *pcm);
@@ -94,4 +92,7 @@ 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);
+snd_pcm_sframes_t pa_alsa_safe_avail_update(snd_pcm_t *pcm, size_t hwbuf_size, const pa_sample_spec *ss);
+int pa_alsa_safe_mmap_begin(snd_pcm_t *pcm, const snd_pcm_channel_area_t **areas, snd_pcm_uframes_t *offset, snd_pcm_uframes_t *frames, size_t hwbuf_size, const pa_sample_spec *ss);
+
#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..36c0a35e
--- /dev/null
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -0,0 +1,558 @@
+/***
+ 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 (!pa_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) {
+ DBusError error;
+ dbus_error_init(&error);
+
+ dbus_bus_remove_match(pa_dbus_connection_get(u->conn), "type='signal',sender='org.bluez',interface='org.bluez.Adapter',member='DeviceRemoved'", &error);
+ dbus_error_free(&error);
+
+ dbus_bus_remove_match(pa_dbus_connection_get(u->conn), "type='signal',sender='org.bluez',interface='org.bluez.Headset',member='PropertyChanged'", &error);
+ dbus_error_free(&error);
+
+ dbus_bus_remove_match(pa_dbus_connection_get(u->conn), "type='signal',sender='org.bluez',interface='org.bluez.AudioSink',member='PropertyChanged'", &error);
+ dbus_error_free(&error);
+
+ dbus_connection_remove_filter(pa_dbus_connection_get(u->conn), filter_cb, u);
+
+ 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/dbus-util.c b/src/modules/dbus-util.c
index 8e0066bc..d2abf087 100644
--- a/src/modules/dbus-util.c
+++ b/src/modules/dbus-util.c
@@ -90,7 +90,7 @@ static pa_io_event_flags_t get_watch_flags(DBusWatch *watch) {
}
/* pa_io_event_cb_t IO event handler */
-static void handle_io_event(PA_GCC_UNUSED pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
+static void handle_io_event(pa_mainloop_api *ea, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
unsigned int flags = 0;
DBusWatch *watch = userdata;
@@ -126,7 +126,7 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struc
dbus_timeout_handle(timeout);
/* restart it for the next scheduled time */
- pa_timeval_add(&next, dbus_timeout_get_interval(timeout) * 1000);
+ pa_timeval_add(&next, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
ea->time_restart(e, &next);
}
}
@@ -192,7 +192,7 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {
return FALSE;
pa_gettimeofday(&tv);
- pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000);
+ pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
ev = c->mainloop->time_new(c->mainloop, &tv, handle_time_event, timeout);
@@ -227,7 +227,7 @@ static void toggle_timeout(DBusTimeout *timeout, void *data) {
struct timeval tv;
pa_gettimeofday(&tv);
- pa_timeval_add(&tv, dbus_timeout_get_interval(timeout) * 1000);
+ pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
c->mainloop->time_restart(ev, &tv);
} else
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 e2b0f7c0..845ede50 100644
--- a/src/modules/gconf/module-gconf.c
+++ b/src/modules/gconf/module-gconf.c
@@ -96,7 +96,7 @@ static int fill_buf(struct userdata *u) {
if ((r = pa_read(u->fd, u->buf + u->buf_fill, BUF_MAX - u->buf_fill, &u->fd_type)) <= 0)
return -1;
- u->buf_fill += r;
+ u->buf_fill += (size_t) r;
return 0;
}
@@ -123,7 +123,7 @@ static char *read_string(struct userdata *u) {
if ((e = memchr(u->buf, 0, u->buf_fill))) {
char *ret = pa_xstrdup(u->buf);
- u->buf_fill -= e - u->buf +1;
+ u->buf_fill -= (size_t) (e - u->buf +1);
memmove(u->buf, e+1, u->buf_fill);
return ret;
}
@@ -164,10 +164,10 @@ static void unload_all_modules(struct userdata *u, struct module_info*m) {
static void load_module(
struct userdata *u,
struct module_info *m,
- int i,
+ unsigned i,
const char *name,
const char *args,
- int is_new) {
+ pa_bool_t is_new) {
pa_module *mod;
@@ -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 aad6801e..6dea172f 100644
--- a/src/modules/module-alsa-sink.c
+++ b/src/modules/module-alsa-sink.c
@@ -28,6 +28,10 @@
#include <asoundlib.h>
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+#include <valgrind/memcheck.h>
+#endif
+
#include <pulse/xmalloc.h>
#include <pulse/util.h>
#include <pulse/timeval.h>
@@ -68,8 +72,7 @@ PA_MODULE_USAGE(
"mmap=<enable memory mapping?> "
"tsched=<enable system timer based scheduling mode?> "
"tsched_buffer_size=<buffer size when using timer based scheduling> "
- "tsched_buffer_watermark=<lower fill watermark> "
- "mixer_reset=<reset hw volume and mute settings to sane defaults when falling back to software?>");
+ "tsched_buffer_watermark=<lower fill watermark>");
static const char* const valid_modargs[] = {
"sink_name",
@@ -85,7 +88,6 @@ static const char* const valid_modargs[] = {
"tsched",
"tsched_buffer_size",
"tsched_buffer_watermark",
- "mixer_reset",
NULL
};
@@ -112,6 +114,8 @@ struct userdata {
long hw_volume_max, hw_volume_min;
long hw_dB_max, hw_dB_min;
pa_bool_t hw_dB_supported;
+ pa_bool_t mixer_seperate_channels;
+ pa_cvolume hardware_volume;
size_t frame_size, fragment_size, hwbuf_size, tsched_watermark;
unsigned nfragments;
@@ -139,7 +143,7 @@ static void fix_tsched_watermark(struct userdata *u) {
size_t min_sleep, min_wakeup;
pa_assert(u);
- max_use = u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size;
+ max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size;
min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->sink->sample_spec);
min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->sink->sample_spec);
@@ -212,8 +216,8 @@ static int try_recover(struct userdata *u, const char *call, int err) {
static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) {
size_t left_to_play;
- if (n*u->frame_size < u->hwbuf_size)
- left_to_play = u->hwbuf_size - (n*u->frame_size);
+ if ((size_t) n*u->frame_size < u->hwbuf_size)
+ left_to_play = u->hwbuf_size - ((size_t) n*u->frame_size);
else
left_to_play = 0;
@@ -237,9 +241,9 @@ static size_t check_left_to_play(struct userdata *u, snd_pcm_sframes_t n) {
return left_to_play;
}
-static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
+static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
int work_done = 0;
- pa_usec_t max_sleep_usec, process_usec;
+ pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_play;
pa_assert(u);
@@ -257,9 +261,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
/* First we determine how many samples are missing to fill the
* buffer up to 100% */
- if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
+ if (PA_UNLIKELY((n = pa_alsa_safe_avail_update(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
- if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
+ if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@@ -275,14 +279,23 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
* need to guarantee that clients only have to keep around
* a single hw buffer length. */
- if (pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) > process_usec+max_sleep_usec/2)
+ if (!polled &&
+ pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) > process_usec+max_sleep_usec/2)
break;
- if (PA_UNLIKELY(n <= u->hwbuf_unused_frames))
+ if (PA_UNLIKELY(n <= u->hwbuf_unused_frames)) {
+
+ if (polled)
+ pa_log("ALSA woke us up to write new data to the device, but there was actually nothing to write! "
+ "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.");
+
break;
+ }
n -= u->hwbuf_unused_frames;
+ polled = FALSE;
+
/* pa_log_debug("Filling up"); */
for (;;) {
@@ -291,10 +304,11 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
int err;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n;
+ snd_pcm_sframes_t sframes;
/* pa_log_debug("%lu frames to write", (unsigned long) frames); */
- if (PA_UNLIKELY((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0)) {
+ if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0)
continue;
@@ -326,9 +340,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
* a little bit longer around? */
pa_memblock_unref_fixed(chunk.memblock);
- if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
+ if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
- if ((r = try_recover(u, "snd_pcm_mmap_commit", err)) == 0)
+ if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
continue;
return r;
@@ -336,7 +350,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
work_done = 1;
- u->frame_index += frames;
+ u->frame_index += (int64_t) frames;
u->since_start += frames * u->frame_size;
/* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
@@ -344,7 +358,7 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
if (frames >= (snd_pcm_uframes_t) n)
break;
- n -= frames;
+ n -= (snd_pcm_sframes_t) frames;
}
}
@@ -352,9 +366,9 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec) {
return work_done;
}
-static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
+static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
int work_done = 0;
- pa_usec_t max_sleep_usec, process_usec;
+ pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_play;
pa_assert(u);
@@ -369,9 +383,9 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
snd_pcm_hwsync(u->pcm_handle);
- if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
+ if (PA_UNLIKELY((n = pa_alsa_safe_avail_update(u->pcm_handle, u->hwbuf_size, &u->sink->sample_spec)) < 0)) {
- if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
+ if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@@ -387,14 +401,23 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
* need to guarantee that clients only have to keep around
* a single hw buffer length. */
- if (pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) > process_usec+max_sleep_usec/2)
+ if (!polled &&
+ pa_bytes_to_usec(left_to_play, &u->sink->sample_spec) > process_usec+max_sleep_usec/2)
break;
- if (PA_UNLIKELY(n <= u->hwbuf_unused_frames))
+ if (PA_UNLIKELY(n <= u->hwbuf_unused_frames)) {
+
+ if (polled)
+ pa_log("ALSA woke us up to write new data to the device, but there was actually nothing to write! "
+ "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.");
+
break;
+ }
n -= u->hwbuf_unused_frames;
+ polled = FALSE;
+
for (;;) {
snd_pcm_sframes_t frames;
void *p;
@@ -402,31 +425,31 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
/* pa_log_debug("%lu frames to write", (unsigned long) frames); */
if (u->memchunk.length <= 0)
- pa_sink_render(u->sink, n * u->frame_size, &u->memchunk);
+ pa_sink_render(u->sink, (size_t) n * u->frame_size, &u->memchunk);
pa_assert(u->memchunk.length > 0);
- frames = u->memchunk.length / u->frame_size;
+ frames = (snd_pcm_sframes_t) (u->memchunk.length / u->frame_size);
if (frames > n)
frames = n;
p = pa_memblock_acquire(u->memchunk.memblock);
- frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, frames);
+ frames = snd_pcm_writei(u->pcm_handle, (const uint8_t*) p + u->memchunk.index, (snd_pcm_uframes_t) frames);
pa_memblock_release(u->memchunk.memblock);
pa_assert(frames != 0);
if (PA_UNLIKELY(frames < 0)) {
- if ((r = try_recover(u, "snd_pcm_writei", n)) == 0)
+ if ((r = try_recover(u, "snd_pcm_writei", (int) frames)) == 0)
continue;
return r;
}
- u->memchunk.index += frames * u->frame_size;
- u->memchunk.length -= frames * u->frame_size;
+ u->memchunk.index += (size_t) frames * u->frame_size;
+ u->memchunk.length -= (size_t) frames * u->frame_size;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@@ -436,7 +459,7 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec) {
work_done = 1;
u->frame_index += frames;
- u->since_start += frames * u->frame_size;
+ u->since_start += (size_t) frames * u->frame_size;
/* pa_log_debug("wrote %lu frames", (unsigned long) frames); */
@@ -490,7 +513,7 @@ static void update_smoother(struct userdata *u) {
/* now1 = pa_timeval_load(&timestamp); */
now1 = pa_rtclock_usec();
- now2 = pa_bytes_to_usec(frames * u->frame_size, &u->sink->sample_spec);
+ now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->sink->sample_spec);
pa_smoother_put(u->smoother, now1, now2);
}
@@ -504,7 +527,7 @@ static pa_usec_t sink_get_latency(struct userdata *u) {
now1 = pa_rtclock_usec();
now2 = pa_smoother_get(u->smoother, now1);
- delay = (int64_t) pa_bytes_to_usec(u->frame_index * u->frame_size, &u->sink->sample_spec) - (int64_t) now2;
+ delay = (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->sink->sample_spec) - (int64_t) now2;
if (delay > 0)
r = (pa_usec_t) delay;
@@ -534,8 +557,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;
@@ -564,7 +587,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);
@@ -573,9 +596,9 @@ static int update_sw_params(struct userdata *u) {
if (PA_UNLIKELY(b < u->frame_size))
b = u->frame_size;
- u->hwbuf_unused_frames =
- PA_LIKELY(b < u->hwbuf_size) ?
- ((u->hwbuf_size - b) / u->frame_size) : 0;
+ u->hwbuf_unused_frames = (snd_pcm_sframes_t)
+ (PA_LIKELY(b < u->hwbuf_size) ?
+ ((u->hwbuf_size - b) / u->frame_size) : 0);
fix_tsched_watermark(u);
}
@@ -584,7 +607,7 @@ static int update_sw_params(struct userdata *u) {
pa_log_debug("hwbuf_unused_frames=%lu", (unsigned long) u->hwbuf_unused_frames);
/* We need at last one frame in the used part of the buffer */
- avail_min = u->hwbuf_unused_frames + 1;
+ avail_min = (snd_pcm_uframes_t) u->hwbuf_unused_frames + 1;
if (u->use_tsched) {
pa_usec_t sleep_usec, process_usec;
@@ -600,7 +623,7 @@ static int update_sw_params(struct userdata *u) {
return err;
}
- pa_sink_set_max_request(u->sink, u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size);
+ pa_sink_set_max_request(u->sink, u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size);
return 0;
}
@@ -618,7 +641,11 @@ static int unsuspend(struct userdata *u) {
pa_log_info("Trying resume...");
snd_config_update_free_global();
- if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
+ if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_PLAYBACK,
+ /*SND_PCM_NONBLOCK|*/
+ SND_PCM_NO_AUTO_RESAMPLE|
+ SND_PCM_NO_AUTO_CHANNELS|
+ SND_PCM_NO_AUTO_FORMAT)) < 0) {
pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err));
goto fail;
}
@@ -645,7 +672,9 @@ static int unsuspend(struct userdata *u) {
}
if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) {
- pa_log_warn("Resume failed, couldn't restore original fragment settings.");
+ pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
+ (unsigned long) u->nfragments, (unsigned long) u->fragment_size,
+ (unsigned long) nfrags, period_size * u->frame_size);
goto fail;
}
@@ -737,40 +766,101 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
return 0;
if (mask & SND_CTL_EVENT_MASK_VALUE) {
- pa_sink_get_volume(u->sink);
- pa_sink_get_mute(u->sink);
+ pa_sink_get_volume(u->sink, TRUE);
+ pa_sink_get_mute(u->sink, TRUE);
}
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;
- int i;
+ unsigned i;
+ pa_cvolume r;
+ char t[PA_CVOLUME_SNPRINT_MAX];
pa_assert(u);
pa_assert(u->mixer_elem);
- for (i = 0; i < s->sample_spec.channels; i++) {
- long alsa_vol;
+ if (u->mixer_seperate_channels) {
- pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, u->mixer_map[i]));
+ r.channels = s->sample_spec.channels;
- if (u->hw_dB_supported) {
+ for (i = 0; i < s->sample_spec.channels; i++) {
+ long alsa_vol;
- if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) >= 0) {
- s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
- continue;
+ if (u->hw_dB_supported) {
+
+ if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
+#endif
+
+ r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
+ } else {
+
+ if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+ r.values[i] = from_alsa_volume(u, alsa_vol);
}
+ }
+
+ } else {
+ long alsa_vol;
+
+ 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;
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ 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 - u->hw_dB_max) / 100.0));
+
+ } else {
+
+ if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+ goto fail;
- u->hw_dB_supported = FALSE;
+ pa_cvolume_set(&r, s->sample_spec.channels, from_alsa_volume(u, alsa_vol));
}
+ }
- if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
- goto fail;
+ pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+
+ if (!pa_cvolume_equal(&u->hardware_volume, &r)) {
+
+ u->hardware_volume = s->volume = r;
+
+ if (u->hw_dB_supported) {
+ pa_cvolume reset;
+
+ /* Hmm, so the hardware volume changed, let's reset our software volume */
- s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
+ pa_cvolume_reset(&reset, s->sample_spec.channels);
+ pa_sink_set_soft_volume(s, &reset);
+ }
}
return 0;
@@ -784,44 +874,101 @@ fail:
static int sink_set_volume_cb(pa_sink *s) {
struct userdata *u = s->userdata;
int err;
- int i;
+ unsigned i;
+ pa_cvolume r;
pa_assert(u);
pa_assert(u->mixer_elem);
- for (i = 0; i < s->sample_spec.channels; i++) {
- long alsa_vol;
- pa_volume_t vol;
+ if (u->mixer_seperate_channels) {
+
+ r.channels = s->sample_spec.channels;
+
+ for (i = 0; i < s->sample_spec.channels; i++) {
+ long alsa_vol;
+ pa_volume_t vol;
+
+ vol = s->volume.values[i];
+
+ if (u->hw_dB_supported) {
- pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, u->mixer_map[i]));
+ alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
+ alsa_vol += u->hw_dB_max;
+ alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
- vol = PA_MIN(s->volume.values[i], PA_VOLUME_NORM);
+ if ((err = snd_mixer_selem_set_playback_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0)
+ goto fail;
+
+ if ((err = snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+ r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
+
+ } 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;
+
+ if ((err = snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+ r.values[i] = from_alsa_volume(u, alsa_vol);
+ }
+ }
+
+ } else {
+ pa_volume_t vol;
+ long alsa_vol;
+
+ vol = pa_cvolume_max(&s->volume);
if (u->hw_dB_supported) {
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
+ alsa_vol += u->hw_dB_max;
alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
- if ((err = snd_mixer_selem_set_playback_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, -1)) >= 0) {
+ 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 (snd_mixer_selem_get_playback_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
- s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
+ pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0));
- continue;
- }
+ } else {
+ alsa_vol = to_alsa_volume(u, vol);
- u->hw_dB_supported = FALSE;
+ 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));
}
+ }
- alsa_vol = (long) roundf(((float) vol * (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);
+ u->hardware_volume = r;
- if ((err = snd_mixer_selem_set_playback_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
- goto fail;
+ if (u->hw_dB_supported) {
+ char t[PA_CVOLUME_SNPRINT_MAX];
- if (snd_mixer_selem_get_playback_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
- s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
- }
+ /* Match exactly what the user requested by software */
+
+ 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));
+ pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
+ pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+
+ } else
+
+ /* We can't match exactly what the user requested, hence let's
+ * at least tell the user about it */
+
+ s->volume = r;
return 0;
@@ -903,7 +1050,7 @@ static int process_rewind(struct userdata *u) {
snd_pcm_hwsync(u->pcm_handle);
if ((unused = snd_pcm_avail_update(u->pcm_handle)) < 0) {
- pa_log("snd_pcm_avail_update() failed: %s", snd_strerror(unused));
+ pa_log("snd_pcm_avail_update() failed: %s", snd_strerror((int) unused));
return -1;
}
@@ -922,15 +1069,15 @@ static int process_rewind(struct userdata *u) {
pa_log_debug("Limited to %lu bytes.", (unsigned long) rewind_nbytes);
- in_frames = (snd_pcm_sframes_t) rewind_nbytes / u->frame_size;
+ in_frames = (snd_pcm_sframes_t) (rewind_nbytes / u->frame_size);
pa_log_debug("before: %lu", (unsigned long) in_frames);
- if ((out_frames = snd_pcm_rewind(u->pcm_handle, in_frames)) < 0) {
- pa_log("snd_pcm_rewind() failed: %s", snd_strerror(out_frames));
+ if ((out_frames = snd_pcm_rewind(u->pcm_handle, (snd_pcm_uframes_t) in_frames)) < 0) {
+ pa_log("snd_pcm_rewind() failed: %s", snd_strerror((int) out_frames));
return -1;
}
pa_log_debug("after: %lu", (unsigned long) out_frames);
- rewind_nbytes = out_frames * u->frame_size;
+ rewind_nbytes = (size_t) out_frames * u->frame_size;
if (rewind_nbytes <= 0)
pa_log_info("Tried rewind, but was apparently not possible.");
@@ -955,6 +1102,7 @@ finish:
static void thread_func(void *userdata) {
struct userdata *u = userdata;
+ unsigned short revents = 0;
pa_assert(u);
@@ -974,16 +1122,16 @@ static void thread_func(void *userdata) {
/* Render some data and write it to the dsp */
if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
int work_done;
- pa_usec_t sleep_usec;
+ pa_usec_t sleep_usec = 0;
if (u->sink->thread_info.rewind_requested)
if (process_rewind(u) < 0)
goto fail;
if (u->use_mmap)
- work_done = mmap_write(u, &sleep_usec);
+ work_done = mmap_write(u, &sleep_usec, revents & POLLOUT);
else
- work_done = unix_write(u, &sleep_usec);
+ work_done = unix_write(u, &sleep_usec, revents & POLLOUT);
if (work_done < 0)
goto fail;
@@ -1042,7 +1190,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)
@@ -1051,7 +1199,6 @@ static void thread_func(void *userdata) {
/* Tell ALSA about this and process its response */
if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
struct pollfd *pollfd;
- unsigned short revents = 0;
int err;
unsigned n;
@@ -1062,7 +1209,7 @@ static void thread_func(void *userdata) {
goto fail;
}
- if (revents & (POLLERR|POLLNVAL|POLLHUP)) {
+ if (revents & (POLLIN|POLLERR|POLLNVAL|POLLHUP|POLLPRI)) {
if (pa_alsa_recover_from_poll(u->pcm_handle, revents) < 0)
goto fail;
@@ -1071,8 +1218,9 @@ static void thread_func(void *userdata) {
}
if (revents && u->use_tsched)
- pa_log_debug("Wakeup from ALSA! (%i)", revents);
- }
+ pa_log_debug("Wakeup from ALSA!%s%s", (revents & POLLIN) ? " INPUT" : "", (revents & POLLOUT) ? " OUTPUT" : "");
+ } else
+ revents = 0;
}
fail:
@@ -1100,7 +1248,7 @@ int pa__init(pa_module*m) {
const char *name;
char *name_buf = NULL;
pa_bool_t namereg_fail;
- pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, mixer_reset = TRUE;
+ pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
pa_usec_t usec;
pa_sink_new_data data;
@@ -1124,11 +1272,11 @@ int pa__init(pa_module*m) {
frame_size = pa_frame_size(&ss);
nfrags = m->core->default_n_fragments;
- frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
+ frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
if (frag_size <= 0)
- frag_size = frame_size;
- tsched_size = pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
- tsched_watermark = pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
+ frag_size = (uint32_t) frame_size;
+ tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
+ tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
@@ -1153,15 +1301,10 @@ int pa__init(pa_module*m) {
}
if (use_tsched && !pa_rtclock_hrtimer()) {
- pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
+ pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
use_tsched = FALSE;
}
- if (pa_modargs_get_value_boolean(ma, "mixer_reset", &mixer_reset) < 0) {
- pa_log("Failed to parse mixer_reset argument.");
- goto fail;
- }
-
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
@@ -1313,7 +1456,7 @@ int pa__init(pa_module*m) {
pa_sink_set_rtpoll(u->sink, u->rtpoll);
u->frame_size = frame_size;
- u->fragment_size = frag_size = period_frames * frame_size;
+ u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
u->nfragments = nfrags;
u->hwbuf_size = u->fragment_size * nfrags;
u->hwbuf_unused_frames = 0;
@@ -1322,6 +1465,8 @@ int pa__init(pa_module*m) {
u->hw_dB_supported = FALSE;
u->hw_dB_min = u->hw_dB_max = 0;
u->hw_volume_min = u->hw_volume_max = 0;
+ u->mixer_seperate_channels = FALSE;
+ pa_cvolume_mute(&u->hardware_volume, u->sink->sample_spec.channels);
if (use_tsched)
fix_tsched_watermark(u);
@@ -1349,76 +1494,60 @@ int pa__init(pa_module*m) {
if (u->mixer_handle) {
pa_assert(u->mixer_elem);
- if (snd_mixer_selem_has_playback_volume(u->mixer_elem))
-
- if (pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0 &&
- snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) >= 0) {
-
- pa_bool_t suitable = TRUE;
+ if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) {
+ 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)
+ pa_log_info("Failed to get volume range. Falling back to software volume control.");
+ 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);
+ suitable = TRUE;
+ }
- if (u->hw_volume_min > u->hw_volume_max) {
-
- pa_log_info("Minimal volume %li larger than maximum volume %li. Strange stuff Falling back to software volume control.", u->hw_volume_min, u->hw_volume_max);
- suitable = FALSE;
-
- } else if (u->hw_volume_max - u->hw_volume_min < 3) {
-
- pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
- suitable = FALSE;
-
- } else if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) >= 0) {
-
- /* u->hw_dB_max = 0; u->hw_dB_min = -3000; Use this to make valgrind shut up */
-
- pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", u->hw_dB_min/100.0, u->hw_dB_max/100.0);
-
- /* Let's see if this thing actually is useful for muting */
- if (u->hw_dB_min > -6000) {
- pa_log_info("Device cannot attenuate for more than -60 dB (only %0.2f dB supported), falling back to software volume control.", ((double) u->hw_dB_min) / 100);
-
- suitable = FALSE;
- } else if (u->hw_dB_max < 0) {
-
- pa_log_info("Device is still attenuated at maximum volume setting (%0.2f dB is maximum). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_max) / 100);
- suitable = FALSE;
+ if (snd_mixer_selem_get_playback_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
+ pa_log_info("Mixer doesn't support dB information.");
+ else {
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min));
+ VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
+#endif
- } else if (u->hw_dB_min >= u->hw_dB_max) {
+ 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;
+ }
+ }
- pa_log_info("Minimal dB (%0.2f) larger or equal to maximum dB (%0.2f). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_min) / 100, ((double) u->hw_dB_max) / 100);
- suitable = FALSE;
+ if (suitable &&
+ !u->hw_dB_supported &&
+ u->hw_volume_max - u->hw_volume_min < 3) {
- } else {
+ pa_log_info("Device doesn't do dB volume and has less than 4 volume levels. Falling back to software volume control.");
+ suitable = FALSE;
+ }
- if (u->hw_dB_max > 0) {
- /* dB > 0 means overamplification, and clipping, we don't want that here */
- pa_log_info("Device can do overamplification for %0.2f dB. Limiting to 0 db", ((double) u->hw_dB_max) / 100);
- u->hw_dB_max = 0;
- }
+ if (suitable) {
+ u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, TRUE) >= 0;
- u->hw_dB_supported = TRUE;
- }
- }
+ u->sink->get_volume = sink_get_volume_cb;
+ u->sink->set_volume = sink_set_volume_cb;
+ u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0);
+ pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
- if (suitable) {
- u->sink->get_volume = sink_get_volume_cb;
- u->sink->set_volume = sink_set_volume_cb;
- u->sink->flags |= PA_SINK_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SINK_DECIBEL_VOLUME : 0);
- pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
-
- } else if (mixer_reset) {
- pa_log_info("Using software volume control. Trying to reset sound card to 0 dB.");
- pa_alsa_0dB_playback(u->mixer_elem);
- } else
- pa_log_info("Using software volume control. Leaving hw mixer controls untouched.");
- }
+ } else
+ pa_log_info("Using software volume control.");
+ }
if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) {
u->sink->get_mute = sink_get_mute_cb;
u->sink->set_mute = sink_set_mute_cb;
u->sink->flags |= PA_SINK_HW_MUTE_CTRL;
- }
+ } else
+ pa_log_info("Using software mute control.");
u->mixer_fdl = pa_alsa_fdlist_new();
diff --git a/src/modules/module-alsa-source.c b/src/modules/module-alsa-source.c
index 1cc467d9..f796ef14 100644
--- a/src/modules/module-alsa-source.c
+++ b/src/modules/module-alsa-source.c
@@ -28,6 +28,10 @@
#include <asoundlib.h>
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+#include <valgrind/memcheck.h>
+#endif
+
#include <pulse/xmalloc.h>
#include <pulse/util.h>
#include <pulse/timeval.h>
@@ -69,8 +73,7 @@ PA_MODULE_USAGE(
"mmap=<enable memory mapping?> "
"tsched=<enable system timer based scheduling mode?> "
"tsched_buffer_size=<buffer size when using timer based scheduling> "
- "tsched_buffer_watermark=<upper fill watermark> "
- "mixer_reset=<reset hw volume and mute settings to sane defaults when falling back to software?>");
+ "tsched_buffer_watermark=<upper fill watermark>");
static const char* const valid_modargs[] = {
"source_name",
@@ -86,7 +89,6 @@ static const char* const valid_modargs[] = {
"tsched",
"tsched_buffer_size",
"tsched_buffer_watermark",
- "mixer_reset",
NULL
};
@@ -113,6 +115,9 @@ struct userdata {
long hw_volume_max, hw_volume_min;
long hw_dB_max, hw_dB_min;
pa_bool_t hw_dB_supported;
+ pa_bool_t mixer_seperate_channels;
+
+ pa_cvolume hardware_volume;
size_t frame_size, fragment_size, hwbuf_size, tsched_watermark;
unsigned nfragments;
@@ -136,7 +141,7 @@ static void fix_tsched_watermark(struct userdata *u) {
size_t min_sleep, min_wakeup;
pa_assert(u);
- max_use = u->hwbuf_size - u->hwbuf_unused_frames * u->frame_size;
+ max_use = u->hwbuf_size - (size_t) u->hwbuf_unused_frames * u->frame_size;
min_sleep = pa_usec_to_bytes(TSCHED_MIN_SLEEP_USEC, &u->source->sample_spec);
min_wakeup = pa_usec_to_bytes(TSCHED_MIN_WAKEUP_USEC, &u->source->sample_spec);
@@ -206,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 (n*u->frame_size < u->hwbuf_size)
- left_to_record = u->hwbuf_size - (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;
@@ -232,9 +238,9 @@ static size_t check_left_to_record(struct userdata *u, snd_pcm_sframes_t n) {
return left_to_record;
}
-static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
+static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
int work_done = 0;
- pa_usec_t max_sleep_usec, process_usec;
+ pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_record;
pa_assert(u);
@@ -249,9 +255,9 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
snd_pcm_hwsync(u->pcm_handle);
- if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
+ if (PA_UNLIKELY((n = pa_alsa_safe_avail_update(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
- if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
+ if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@@ -260,11 +266,20 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
left_to_record = check_left_to_record(u, n);
if (u->use_tsched)
- if (pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
+ if (!polled &&
+ pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
break;
- if (PA_UNLIKELY(n <= 0))
+ if (PA_UNLIKELY(n <= 0)) {
+
+ if (polled)
+ pa_log("ALSA woke us up to read new data from the device, but there was actually nothing to read! "
+ "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio device.");
+
break;
+ }
+
+ polled = FALSE;
for (;;) {
int err;
@@ -272,10 +287,11 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
snd_pcm_uframes_t offset, frames = (snd_pcm_uframes_t) n;
pa_memchunk chunk;
void *p;
+ snd_pcm_sframes_t sframes;
/* pa_log_debug("%lu frames to read", (unsigned long) frames); */
- if (PA_UNLIKELY((err = snd_pcm_mmap_begin(u->pcm_handle, &areas, &offset, &frames)) < 0)) {
+ if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0)
continue;
@@ -304,9 +320,9 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
pa_source_post(u->source, &chunk);
pa_memblock_unref_fixed(chunk.memblock);
- if (PA_UNLIKELY((err = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
+ if (PA_UNLIKELY((sframes = snd_pcm_mmap_commit(u->pcm_handle, offset, frames)) < 0)) {
- if ((r = try_recover(u, "snd_pcm_mmap_commit", err)) == 0)
+ if ((r = try_recover(u, "snd_pcm_mmap_commit", (int) sframes)) == 0)
continue;
return r;
@@ -314,14 +330,14 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
work_done = 1;
- u->frame_index += frames;
+ u->frame_index += (int64_t) frames;
/* pa_log_debug("read %lu frames", (unsigned long) frames); */
if (frames >= (snd_pcm_uframes_t) n)
break;
- n -= frames;
+ n -= (snd_pcm_sframes_t) frames;
}
}
@@ -329,9 +345,9 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec) {
return work_done;
}
-static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
+static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled) {
int work_done = 0;
- pa_usec_t max_sleep_usec, process_usec;
+ pa_usec_t max_sleep_usec = 0, process_usec = 0;
size_t left_to_record;
pa_assert(u);
@@ -346,9 +362,9 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
snd_pcm_hwsync(u->pcm_handle);
- if (PA_UNLIKELY((n = snd_pcm_avail_update(u->pcm_handle)) < 0)) {
+ if (PA_UNLIKELY((n = pa_alsa_safe_avail_update(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
- if ((r = try_recover(u, "snd_pcm_avail_update", n)) == 0)
+ if ((r = try_recover(u, "snd_pcm_avail_update", (int) n)) == 0)
continue;
return r;
@@ -357,11 +373,20 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
left_to_record = check_left_to_record(u, n);
if (u->use_tsched)
- if (pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
+ if (!polled &&
+ pa_bytes_to_usec(left_to_record, &u->source->sample_spec) > process_usec+max_sleep_usec/2)
break;
- if (PA_UNLIKELY(n <= 0))
+ if (PA_UNLIKELY(n <= 0)) {
+
+ if (polled)
+ pa_log("ALSA woke us up to read new data from the device, but there was actually nothing to read! "
+ "Most likely this is an ALSA driver bug. Please report this issue to the PulseAudio developers.");
+
return work_done;
+ }
+
+ polled = FALSE;
for (;;) {
void *p;
@@ -370,7 +395,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1);
- frames = pa_memblock_get_length(chunk.memblock) / u->frame_size;
+ frames = (snd_pcm_sframes_t) (pa_memblock_get_length(chunk.memblock) / u->frame_size);
if (frames > n)
frames = n;
@@ -378,7 +403,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
/* pa_log_debug("%lu frames to read", (unsigned long) n); */
p = pa_memblock_acquire(chunk.memblock);
- frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, frames);
+ frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames);
pa_memblock_release(chunk.memblock);
pa_assert(frames != 0);
@@ -386,14 +411,14 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec) {
if (PA_UNLIKELY(frames < 0)) {
pa_memblock_unref(chunk.memblock);
- if ((r = try_recover(u, "snd_pcm_readi", n)) == 0)
+ if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0)
continue;
return r;
}
chunk.index = 0;
- chunk.length = frames * u->frame_size;
+ chunk.length = (size_t) frames * u->frame_size;
pa_source_post(u->source, &chunk);
pa_memblock_unref(chunk.memblock);
@@ -437,7 +462,7 @@ static void update_smoother(struct userdata *u) {
frames = u->frame_index + delay;
now1 = pa_rtclock_usec();
- now2 = pa_bytes_to_usec(frames * u->frame_size, &u->source->sample_spec);
+ now2 = pa_bytes_to_usec((uint64_t) frames * u->frame_size, &u->source->sample_spec);
pa_smoother_put(u->smoother, now1, now2);
}
@@ -452,7 +477,7 @@ static pa_usec_t source_get_latency(struct userdata *u) {
now1 = pa_rtclock_usec();
now2 = pa_smoother_get(u->smoother, now1);
- delay = (int64_t) now2 - pa_bytes_to_usec(u->frame_index * u->frame_size, &u->source->sample_spec);
+ delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec((uint64_t) u->frame_index * u->frame_size, &u->source->sample_spec);
if (delay > 0)
r = (pa_usec_t) delay;
@@ -508,7 +533,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);
@@ -517,9 +542,9 @@ static int update_sw_params(struct userdata *u) {
if (PA_UNLIKELY(b < u->frame_size))
b = u->frame_size;
- u->hwbuf_unused_frames =
- PA_LIKELY(b < u->hwbuf_size) ?
- ((u->hwbuf_size - b) / u->frame_size) : 0;
+ u->hwbuf_unused_frames = (snd_pcm_sframes_t)
+ (PA_LIKELY(b < u->hwbuf_size) ?
+ ((u->hwbuf_size - b) / u->frame_size) : 0);
fix_tsched_watermark(u);
}
@@ -559,7 +584,12 @@ static int unsuspend(struct userdata *u) {
pa_log_info("Trying resume...");
snd_config_update_free_global();
- if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
+
+ if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
+ /*SND_PCM_NONBLOCK|*/
+ SND_PCM_NO_AUTO_RESAMPLE|
+ SND_PCM_NO_AUTO_CHANNELS|
+ SND_PCM_NO_AUTO_FORMAT)) < 0) {
pa_log("Error opening PCM device %s: %s", u->device_name, snd_strerror(err));
goto fail;
}
@@ -586,7 +616,9 @@ static int unsuspend(struct userdata *u) {
}
if (nfrags != u->nfragments || period_size*u->frame_size != u->fragment_size) {
- pa_log_warn("Resume failed, couldn't restore original fragment settings.");
+ pa_log_warn("Resume failed, couldn't restore original fragment settings. (Old: %lu*%lu, New %lu*%lu)",
+ (unsigned long) u->nfragments, (unsigned long) u->fragment_size,
+ (unsigned long) nfrags, period_size * u->frame_size);
goto fail;
}
@@ -680,40 +712,101 @@ static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
return 0;
if (mask & SND_CTL_EVENT_MASK_VALUE) {
- pa_source_get_volume(u->source);
- pa_source_get_mute(u->source);
+ pa_source_get_volume(u->source, TRUE);
+ pa_source_get_mute(u->source, TRUE);
}
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;
- int i;
+ unsigned i;
+ pa_cvolume r;
+ char t[PA_CVOLUME_SNPRINT_MAX];
pa_assert(u);
pa_assert(u->mixer_elem);
- for (i = 0; i < s->sample_spec.channels; i++) {
- long alsa_vol;
+ if (u->mixer_seperate_channels) {
- pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, u->mixer_map[i]));
+ r.channels = s->sample_spec.channels;
- if (u->hw_dB_supported) {
+ for (i = 0; i < s->sample_spec.channels; i++) {
+ long alsa_vol;
- if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) >= 0) {
- s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
- continue;
+ if (u->hw_dB_supported) {
+
+ if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&alsa_vol, sizeof(alsa_vol));
+#endif
+
+ r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
+ } else {
+
+ if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+ r.values[i] = from_alsa_volume(u, alsa_vol);
}
+ }
+
+ } else {
+ long alsa_vol;
+
+ 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;
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ 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 - u->hw_dB_max) / 100.0));
+
+ } else {
- u->hw_dB_supported = FALSE;
+ 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));
}
+ }
- if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
- goto fail;
+ pa_log_debug("Read hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+
+ if (!pa_cvolume_equal(&u->hardware_volume, &r)) {
+
+ u->hardware_volume = s->volume = r;
+
+ if (u->hw_dB_supported) {
+ pa_cvolume reset;
+
+ /* Hmm, so the hardware volume changed, let's reset our software volume */
- s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
+ pa_cvolume_reset(&reset, s->sample_spec.channels);
+ pa_source_set_soft_volume(s, &reset);
+ }
}
return 0;
@@ -727,44 +820,101 @@ fail:
static int source_set_volume_cb(pa_source *s) {
struct userdata *u = s->userdata;
int err;
- int i;
+ unsigned i;
+ pa_cvolume r;
pa_assert(u);
pa_assert(u->mixer_elem);
- for (i = 0; i < s->sample_spec.channels; i++) {
- long alsa_vol;
- pa_volume_t vol;
+ if (u->mixer_seperate_channels) {
+
+ r.channels = s->sample_spec.channels;
+
+ for (i = 0; i < s->sample_spec.channels; i++) {
+ long alsa_vol;
+ pa_volume_t vol;
- pa_assert(snd_mixer_selem_has_capture_channel(u->mixer_elem, u->mixer_map[i]));
+ vol = s->volume.values[i];
- vol = PA_MIN(s->volume.values[i], PA_VOLUME_NORM);
+ if (u->hw_dB_supported) {
+
+ alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
+ alsa_vol += u->hw_dB_max;
+ alsa_vol = PA_CLAMP_UNLIKELY(alsa_vol, u->hw_dB_min, u->hw_dB_max);
+
+ if ((err = snd_mixer_selem_set_capture_dB(u->mixer_elem, u->mixer_map[i], alsa_vol, 1)) < 0)
+ goto fail;
+
+ if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+ r.values[i] = pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0);
+
+ } 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;
+
+ if ((err = snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol)) < 0)
+ goto fail;
+
+ r.values[i] = from_alsa_volume(u, alsa_vol);
+ }
+ }
+
+ } else {
+ pa_volume_t vol;
+ long alsa_vol;
+
+ vol = pa_cvolume_max(&s->volume);
if (u->hw_dB_supported) {
alsa_vol = (long) (pa_sw_volume_to_dB(vol) * 100);
+ alsa_vol += u->hw_dB_max;
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(u->mixer_elem, u->mixer_map[i], alsa_vol, -1)) >= 0) {
+ if ((err = snd_mixer_selem_get_capture_dB(u->mixer_elem, SND_MIXER_SCHN_MONO, &alsa_vol)) < 0)
+ goto fail;
- if (snd_mixer_selem_get_capture_dB(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
- s->volume.values[i] = pa_sw_volume_from_dB(alsa_vol / 100.0);
+ pa_cvolume_set(&r, s->volume.channels, pa_sw_volume_from_dB((double) (alsa_vol - u->hw_dB_max) / 100.0));
- continue;
- }
+ } 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;
- u->hw_dB_supported = FALSE;
+ 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));
}
+ }
- alsa_vol = (long) roundf(((float) vol * (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);
+ u->hardware_volume = r;
- if ((err = snd_mixer_selem_set_capture_volume(u->mixer_elem, u->mixer_map[i], alsa_vol)) < 0)
- goto fail;
+ if (u->hw_dB_supported) {
+ char t[PA_CVOLUME_SNPRINT_MAX];
- if (snd_mixer_selem_get_capture_volume(u->mixer_elem, u->mixer_map[i], &alsa_vol) >= 0)
- s->volume.values[i] = (pa_volume_t) roundf(((float) (alsa_vol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
- }
+ /* Match exactly what the user requested by software */
+
+ 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));
+ pa_log_debug("Got hardware volume: %s", pa_cvolume_snprint(t, sizeof(t), &u->hardware_volume));
+ pa_log_debug("Calculated software volume: %s", pa_cvolume_snprint(t, sizeof(t), &r));
+
+ } else
+
+ /* We can't match exactly what the user requested, hence let's
+ * at least tell the user about it */
+
+ s->volume = r;
return 0;
@@ -818,6 +968,7 @@ static void source_update_requested_latency_cb(pa_source *s) {
static void thread_func(void *userdata) {
struct userdata *u = userdata;
+ unsigned short revents = 0;
pa_assert(u);
@@ -837,12 +988,12 @@ static void thread_func(void *userdata) {
/* Read some data and pass it to the sources */
if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
int work_done = 0;
- pa_usec_t sleep_usec;
+ pa_usec_t sleep_usec = 0;
if (u->use_mmap)
- work_done = mmap_read(u, &sleep_usec);
+ work_done = mmap_read(u, &sleep_usec, revents & POLLIN);
else
- work_done = unix_read(u, &sleep_usec);
+ work_done = unix_read(u, &sleep_usec, revents & POLLIN);
if (work_done < 0)
goto fail;
@@ -875,7 +1026,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)
@@ -884,7 +1035,6 @@ static void thread_func(void *userdata) {
/* Tell ALSA about this and process its response */
if (PA_SOURCE_IS_OPENED(u->source->thread_info.state)) {
struct pollfd *pollfd;
- unsigned short revents = 0;
int err;
unsigned n;
@@ -895,7 +1045,7 @@ static void thread_func(void *userdata) {
goto fail;
}
- if (revents & (POLLERR|POLLNVAL|POLLHUP)) {
+ if (revents & (POLLOUT|POLLERR|POLLNVAL|POLLHUP|POLLPRI)) {
if (pa_alsa_recover_from_poll(u->pcm_handle, revents) < 0)
goto fail;
@@ -903,8 +1053,9 @@ static void thread_func(void *userdata) {
}
if (revents && u->use_tsched)
- pa_log_debug("Wakeup from ALSA! (%i)", revents);
- }
+ pa_log_debug("Wakeup from ALSA!%s%s", (revents & POLLIN) ? " INPUT" : "", (revents & POLLOUT) ? " OUTPUT" : "");
+ } else
+ revents = 0;
}
fail:
@@ -932,7 +1083,7 @@ int pa__init(pa_module*m) {
const char *name;
char *name_buf = NULL;
pa_bool_t namereg_fail;
- pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d, mixer_reset = TRUE;
+ pa_bool_t use_mmap = TRUE, b, use_tsched = TRUE, d;
pa_source_new_data data;
snd_pcm_info_alloca(&pcm_info);
@@ -955,11 +1106,11 @@ int pa__init(pa_module*m) {
frame_size = pa_frame_size(&ss);
nfrags = m->core->default_n_fragments;
- frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
+ frag_size = (uint32_t) pa_usec_to_bytes(m->core->default_fragment_size_msec*PA_USEC_PER_MSEC, &ss);
if (frag_size <= 0)
- frag_size = frame_size;
- tsched_size = pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
- tsched_watermark = pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
+ frag_size = (uint32_t) frame_size;
+ tsched_size = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_BUFFER_USEC, &ss);
+ tsched_watermark = (uint32_t) pa_usec_to_bytes(DEFAULT_TSCHED_WATERMARK_USEC, &ss);
if (pa_modargs_get_value_u32(ma, "fragments", &nfrags) < 0 ||
pa_modargs_get_value_u32(ma, "fragment_size", &frag_size) < 0 ||
@@ -984,15 +1135,10 @@ int pa__init(pa_module*m) {
}
if (use_tsched && !pa_rtclock_hrtimer()) {
- pa_log("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
+ pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
use_tsched = FALSE;
}
- if (pa_modargs_get_value_boolean(ma, "mixer_reset", &mixer_reset) < 0) {
- pa_log("Failed to parse mixer_reset argument.");
- goto fail;
- }
-
u = pa_xnew0(struct userdata, 1);
u->core = m->core;
u->module = m;
@@ -1137,7 +1283,7 @@ int pa__init(pa_module*m) {
pa_source_set_rtpoll(u->source, u->rtpoll);
u->frame_size = frame_size;
- u->fragment_size = frag_size = period_frames * frame_size;
+ u->fragment_size = frag_size = (uint32_t) (period_frames * frame_size);
u->nfragments = nfrags;
u->hwbuf_size = u->fragment_size * nfrags;
u->hwbuf_unused_frames = 0;
@@ -1146,6 +1292,8 @@ int pa__init(pa_module*m) {
u->hw_dB_supported = FALSE;
u->hw_dB_min = u->hw_dB_max = 0;
u->hw_volume_min = u->hw_volume_max = 0;
+ u->mixer_seperate_channels = FALSE;
+ pa_cvolume_mute(&u->hardware_volume, u->source->sample_spec.channels);
if (use_tsched)
fix_tsched_watermark(u);
@@ -1168,67 +1316,59 @@ int pa__init(pa_module*m) {
if (u->mixer_handle) {
pa_assert(u->mixer_elem);
- if (snd_mixer_selem_has_capture_volume(u->mixer_elem))
- if (pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0 &&
- snd_mixer_selem_get_capture_volume_range(u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max) >= 0) {
-
- pa_bool_t suitable = TRUE;
+ if (snd_mixer_selem_has_capture_volume(u->mixer_elem)) {
+ 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)
+ pa_log_info("Failed to get volume range. Falling back to software volume control.");
+ 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);
+ suitable = TRUE;
+ }
- if (u->hw_volume_min > u->hw_volume_max) {
-
- pa_log_info("Minimal volume %li larger than maximum volume %li. Strange stuff Falling back to software volume control.", u->hw_volume_min, u->hw_volume_max);
- suitable = FALSE;
-
- } else if (u->hw_volume_max - u->hw_volume_min < 3) {
-
- pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
- suitable = FALSE;
-
- } else if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) >= 0) {
-
- pa_log_info("Volume ranges from %0.2f dB to %0.2f dB.", u->hw_dB_min/100.0, u->hw_dB_max/100.0);
-
- /* Let's see if this thing actually is useful for muting */
- if (u->hw_dB_min > -6000) {
- pa_log_info("Device cannot attenuate for more than -60 dB (only %0.2f dB supported), falling back to software volume control.", ((double) u->hw_dB_min) / 100);
-
- suitable = FALSE;
- } else if (u->hw_dB_max < 0) {
-
- pa_log_info("Device is still attenuated at maximum volume setting (%0.2f dB is maximum). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_max) / 100);
- suitable = FALSE;
-
- } else if (u->hw_dB_min >= u->hw_dB_max) {
-
- pa_log_info("Minimal dB (%0.2f) larger or equal to maximum dB (%0.2f). Strange stuff. Falling back to software volume control.", ((double) u->hw_dB_min) / 100, ((double) u->hw_dB_max) / 100);
- suitable = FALSE;
+ if (snd_mixer_selem_get_capture_dB_range(u->mixer_elem, &u->hw_dB_min, &u->hw_dB_max) < 0)
+ pa_log_info("Mixer doesn't support dB information.");
+ else {
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+ VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_min, sizeof(u->hw_dB_min));
+ VALGRIND_MAKE_MEM_DEFINED(&u->hw_dB_max, sizeof(u->hw_dB_max));
+#endif
- } else
- 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) {
- u->source->get_volume = source_get_volume_cb;
- u->source->set_volume = source_set_volume_cb;
- u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0);
- pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
-
- } else if (mixer_reset) {
- pa_log_info("Using software volume control. Trying to reset sound card to 0 dB.");
- pa_alsa_0dB_capture(u->mixer_elem);
- } else
- pa_log_info("Using software volume control. Leaving hw mixer controls untouched.");
+ if (suitable &&
+ !u->hw_dB_supported &&
+ u->hw_volume_max - u->hw_volume_min < 3) {
+ pa_log_info("Device has less than 4 volume levels. Falling back to software volume control.");
+ suitable = FALSE;
}
+ if (suitable) {
+ u->mixer_seperate_channels = pa_alsa_calc_mixer_map(u->mixer_elem, &map, u->mixer_map, FALSE) >= 0;
+
+ u->source->get_volume = source_get_volume_cb;
+ u->source->set_volume = source_set_volume_cb;
+ u->source->flags |= PA_SOURCE_HW_VOLUME_CTRL | (u->hw_dB_supported ? PA_SOURCE_DECIBEL_VOLUME : 0);
+ pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->hw_dB_supported ? "supported" : "not supported");
+ } else
+ pa_log_info("Using software volume control.");
+ }
if (snd_mixer_selem_has_capture_switch(u->mixer_elem)) {
u->source->get_mute = source_get_mute_cb;
u->source->set_mute = source_set_mute_cb;
u->source->flags |= PA_SOURCE_HW_MUTE_CTRL;
- }
+ } else
+ pa_log_info("Using software mute control.");
u->mixer_fdl = pa_alsa_fdlist_new();
diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c
index 1bfe4b4c..d61d127a 100644
--- a/src/modules/module-combine.c
+++ b/src/modules/module-combine.c
@@ -206,9 +206,9 @@ static void adjust_rates(struct userdata *u) {
continue;
if (o->total_latency < target_latency)
- r -= (uint32_t) (((((double) target_latency - o->total_latency))/u->adjust_time)*r/PA_USEC_PER_SEC);
+ r -= (uint32_t) ((((double) (target_latency - o->total_latency))/(double)u->adjust_time)*(double)r/PA_USEC_PER_SEC);
else if (o->total_latency > target_latency)
- r += (uint32_t) (((((double) o->total_latency - target_latency))/u->adjust_time)*r/PA_USEC_PER_SEC);
+ r += (uint32_t) ((((double) (o->total_latency - target_latency))/(double)u->adjust_time)*(double)r/PA_USEC_PER_SEC);
if (r < (uint32_t) (base_rate*0.9) || r > (uint32_t) (base_rate*1.1)) {
pa_log_warn("[%s] sample rates too different, not adjusting (%u vs. %u).", pa_proplist_gets(o->sink_input->proplist, PA_PROP_MEDIA_NAME), base_rate, r);
@@ -233,7 +233,7 @@ static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct time
adjust_rates(u);
pa_gettimeofday(&n);
- n.tv_sec += u->adjust_time;
+ n.tv_sec += (time_t) u->adjust_time;
u->sink->core->mainloop->time_restart(e, &n);
}
@@ -389,7 +389,7 @@ static void request_memblock(struct output *o, size_t length) {
/* OK, we need to prepare new data, but only if the sink is actually running */
if (pa_atomic_load(&o->userdata->thread_info.running))
- pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, length, NULL);
+ pa_asyncmsgq_send(o->outq, PA_MSGOBJECT(o->userdata->sink), SINK_MESSAGE_NEED, o, (int64_t) length, NULL);
}
/* Called from I/O thread context */
@@ -1159,7 +1159,7 @@ int pa__init(pa_module*m) {
if (u->adjust_time > 0) {
struct timeval tv;
pa_gettimeofday(&tv);
- tv.tv_sec += u->adjust_time;
+ tv.tv_sec += (time_t) u->adjust_time;
u->time_event = m->core->mainloop->time_new(m->core->mainloop, &tv, time_callback, u);
}
diff --git a/src/modules/module-detect.c b/src/modules/module-detect.c
index 09b720df..1616d47c 100644
--- a/src/modules/module-detect.c
+++ b/src/modules/module-detect.c
@@ -236,16 +236,16 @@ int pa__init(pa_module*m) {
goto fail;
}
-#if HAVE_ALSA
+#ifdef HAVE_ALSA
if ((n = detect_alsa(m->core, just_one)) <= 0)
#endif
#if HAVE_OSS
if ((n = detect_oss(m->core, just_one)) <= 0)
#endif
-#if HAVE_SOLARIS
+#ifdef HAVE_SOLARIS
if ((n = detect_solaris(m->core, just_one)) <= 0)
#endif
-#if OS_IS_WIN32
+#ifdef OS_IS_WIN32
if ((n = detect_waveout(m->core, just_one)) <= 0)
#endif
{
diff --git a/src/modules/module-device-restore.c b/src/modules/module-device-restore.c
index 3d731f12..86a78810 100644
--- a/src/modules/module-device-restore.c
+++ b/src/modules/module-device-restore.c
@@ -106,7 +106,7 @@ static struct entry* read_entry(struct userdata *u, char *name) {
pa_assert(name);
key.dptr = name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@@ -179,8 +179,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
name = pa_sprintf_malloc("sink:%s", sink->name);
entry.channel_map = sink->channel_map;
- entry.volume = *pa_sink_get_volume(sink);
- entry.muted = pa_sink_get_mute(sink);
+ entry.volume = *pa_sink_get_volume(sink, FALSE);
+ entry.muted = pa_sink_get_mute(sink, FALSE);
} else {
pa_source *source;
@@ -192,8 +192,8 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
name = pa_sprintf_malloc("source:%s", source->name);
entry.channel_map = source->channel_map;
- entry.volume = *pa_source_get_volume(source);
- entry.muted = pa_source_get_mute(source);
+ entry.volume = *pa_source_get_volume(source, FALSE);
+ entry.muted = pa_source_get_mute(source, FALSE);
}
if ((old = read_entry(u, name))) {
@@ -210,7 +210,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
}
key.dptr = name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
@@ -288,6 +288,7 @@ int pa__init(pa_module*m) {
pa_source *source;
uint32_t idx;
pa_bool_t restore_volume = TRUE, restore_muted = TRUE;
+ int gdbm_cache_size;
pa_assert(m);
@@ -337,6 +338,10 @@ int pa__init(pa_module*m) {
goto fail;
}
+ /* By default the cache of gdbm is rather large, let's reduce it a bit to save memory */
+ gdbm_cache_size = 10;
+ gdbm_setopt(u->gdbm_file, GDBM_CACHESIZE, &gdbm_cache_size, sizeof(gdbm_cache_size));
+
pa_log_info("Sucessfully opened database file '%s'.", fname);
pa_xfree(fname);
diff --git a/src/modules/module-esound-compat-spawnpid.c b/src/modules/module-esound-compat-spawnpid.c
index f75335d5..882dba8c 100644
--- a/src/modules/module-esound-compat-spawnpid.c
+++ b/src/modules/module-esound-compat-spawnpid.c
@@ -62,7 +62,7 @@ int pa__init(pa_module*m) {
goto finish;
}
- if (kill(pid, SIGUSR1) < 0)
+ if (kill((pid_t) pid, SIGUSR1) < 0)
pa_log_warn("kill(%u) failed: %s", pid, pa_cstrerror(errno));
pa_module_unload_request(m, TRUE);
diff --git a/src/modules/module-esound-sink.c b/src/modules/module-esound-sink.c
index f748808e..14f1810a 100644
--- a/src/modules/module-esound-sink.c
+++ b/src/modules/module-esound-sink.c
@@ -165,7 +165,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_usec_t w, r;
r = pa_smoother_get(u->smoother, pa_rtclock_usec());
- w = pa_bytes_to_usec(u->offset + u->memchunk.length, &u->sink->sample_spec);
+ w = pa_bytes_to_usec((uint64_t) u->offset + u->memchunk.length, &u->sink->sample_spec);
*((pa_usec_t*) data) = w > r ? w - r : 0;
break;
@@ -250,8 +250,8 @@ static void thread_func(void *userdata) {
} else {
u->offset += l;
- u->memchunk.index += l;
- u->memchunk.length -= l;
+ u->memchunk.index += (size_t) l;
+ u->memchunk.length -= (size_t) l;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@@ -285,7 +285,7 @@ static void thread_func(void *userdata) {
}
#endif
- usec = pa_bytes_to_usec(n, &u->sink->sample_spec);
+ usec = pa_bytes_to_usec((uint64_t) n, &u->sink->sample_spec);
if (usec > u->latency)
usec -= u->latency;
@@ -296,7 +296,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
- pollfd->events = PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0;
+ pollfd->events = (short) (PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0);
}
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
@@ -342,7 +342,7 @@ static int do_write(struct userdata *u) {
return -1;
}
- u->write_index += r;
+ u->write_index += (size_t) r;
pa_assert(u->write_index <= u->write_length);
if (u->write_index == u->write_length) {
@@ -458,7 +458,7 @@ static int do_read(struct userdata *u) {
return -1;
}
- u->read_index += r;
+ u->read_index += (size_t) r;
pa_assert(u->read_index <= u->read_length);
if (u->read_index == u->read_length)
@@ -468,7 +468,7 @@ static int do_read(struct userdata *u) {
return 0;
}
-static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) {
+static void io_callback(pa_iochannel *io, void*userdata) {
struct userdata *u = userdata;
pa_assert(u);
@@ -483,7 +483,7 @@ static void io_callback(PA_GCC_UNUSED pa_iochannel *io, void*userdata) {
}
}
-static void on_connection(PA_GCC_UNUSED pa_socket_client *c, pa_iochannel*io, void *userdata) {
+static void on_connection(pa_socket_client *c, pa_iochannel*io, void *userdata) {
struct userdata *u = userdata;
pa_socket_client_unref(u->client);
@@ -545,7 +545,7 @@ int pa__init(pa_module*m) {
u->format =
(ss.format == PA_SAMPLE_U8 ? ESD_BITS8 : ESD_BITS16) |
(ss.channels == 2 ? ESD_STEREO : ESD_MONO);
- u->rate = ss.rate;
+ u->rate = (int32_t) ss.rate;
u->block_size = pa_usec_to_bytes(PA_USEC_PER_SEC/20, &ss);
u->read_data = u->write_data = NULL;
diff --git a/src/modules/module-flat-volume.c b/src/modules/module-flat-volume.c
new file mode 100644
index 00000000..9bc8055a
--- /dev/null
+++ b/src/modules/module-flat-volume.c
@@ -0,0 +1,224 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ Copyright 2004-2006, 2008 Lennart Poettering
+
+ Contact: Marc-Andre Lureau <marc-andre.lureau@nokia.com>
+
+ 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 <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/sink-input.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/macro.h>
+
+#include "module-flat-volume-symdef.h"
+
+PA_MODULE_AUTHOR("Marc-Andre Lureau");
+PA_MODULE_DESCRIPTION("Flat volume");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+PA_MODULE_USAGE("");
+
+struct userdata {
+ pa_subscription *subscription;
+ pa_hook_slot *sink_input_set_volume_hook_slot;
+ pa_hook_slot *sink_input_fixate_hook_slot;
+};
+
+static void process_input_volume_change(
+ pa_cvolume *dest_volume,
+ const pa_cvolume *dest_virtual_volume,
+ pa_channel_map *dest_channel_map,
+ pa_sink_input *this,
+ pa_sink *sink) {
+
+ pa_sink_input *i;
+ uint32_t idx;
+ pa_cvolume max_volume, sink_volume;
+
+ pa_assert(dest_volume);
+ pa_assert(dest_virtual_volume);
+ pa_assert(dest_channel_map);
+ pa_assert(sink);
+
+ if (!(sink->flags & PA_SINK_DECIBEL_VOLUME))
+ return;
+
+ pa_log_debug("Sink input volume changed");
+
+ max_volume = *dest_virtual_volume;
+ pa_cvolume_remap(&max_volume, dest_channel_map, &sink->channel_map);
+
+ for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &idx))) {
+ /* skip this sink-input if we are processing a volume change request */
+ if (this && this == i)
+ continue;
+
+ if (pa_cvolume_max(&i->virtual_volume) > pa_cvolume_max(&max_volume)) {
+ max_volume = i->virtual_volume;
+ pa_cvolume_remap(&max_volume, &i->channel_map, &sink->channel_map);
+ }
+ }
+
+ /* Set the master volume, and normalize inputs */
+ if (!pa_cvolume_equal(&max_volume, &sink->volume)) {
+
+ pa_sink_set_volume(sink, &max_volume);
+
+ pa_log_debug("sink = %.2f (changed)", (double)pa_cvolume_avg(&sink->volume)/PA_VOLUME_NORM);
+
+ /* Now, normalize each of the internal volume (client sink-input volume / sink master volume) */
+ for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &idx))) {
+ /* skip this sink-input if we are processing a volume change request */
+ if (this && this == i)
+ continue;
+
+ sink_volume = max_volume;
+ pa_cvolume_remap(&sink_volume, &sink->channel_map, &i->channel_map);
+ pa_sw_cvolume_divide(&i->volume, &i->virtual_volume, &sink_volume);
+ pa_log_debug("sink input { id = %d, flat = %.2f, true = %.2f }",
+ i->index,
+ (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,
+ (double)pa_cvolume_avg(&i->volume)/PA_VOLUME_NORM);
+ pa_asyncmsgq_post(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, pa_xnewdup(struct pa_cvolume, &i->volume, 1), 0, NULL, pa_xfree);
+ }
+ } else
+ pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(&sink->volume)/PA_VOLUME_NORM);
+
+ /* and this one */
+
+ sink_volume = max_volume;
+ pa_cvolume_remap(&sink_volume, &sink->channel_map, dest_channel_map);
+ pa_sw_cvolume_divide(dest_volume, dest_virtual_volume, &sink_volume);
+ pa_log_debug("caller sink input: { id = %d, flat = %.2f, true = %.2f }",
+ this ? (int)this->index : -1,
+ (double)pa_cvolume_avg(dest_virtual_volume)/PA_VOLUME_NORM,
+ (double)pa_cvolume_avg(dest_volume)/PA_VOLUME_NORM);
+}
+
+static pa_hook_result_t sink_input_set_volume_hook_callback(pa_core *c, pa_sink_input_set_volume_data *this, struct userdata *u) {
+ pa_assert(this);
+ pa_assert(this->sink_input);
+
+ process_input_volume_change(&this->volume, &this->virtual_volume, &this->sink_input->channel_map,
+ this->sink_input, this->sink_input->sink);
+
+ return PA_HOOK_OK;
+}
+
+static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *core, pa_sink_input_new_data *this, struct userdata *u) {
+ pa_assert(this);
+ pa_assert(this->sink);
+
+ process_input_volume_change(&this->volume, &this->virtual_volume, &this->channel_map,
+ NULL, this->sink);
+
+ return PA_HOOK_OK;
+}
+
+static void subscribe_callback(pa_core *core, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {
+ struct userdata *u = userdata;
+ pa_sink *sink;
+ pa_sink_input *i;
+ uint32_t iidx;
+ pa_cvolume sink_volume;
+
+ pa_assert(core);
+ pa_assert(u);
+
+ if (t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_NEW) &&
+ t != (PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE))
+ return;
+
+ if (!(sink = pa_idxset_get_by_index(core->sinks, idx)))
+ return;
+
+ if (!(sink->flags & PA_SINK_DECIBEL_VOLUME))
+ return;
+
+ pa_log_debug("Sink volume changed");
+ pa_log_debug("sink = %.2f", (double)pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)) / PA_VOLUME_NORM);
+
+ sink_volume = *pa_sink_get_volume(sink, FALSE);
+
+ for (i = PA_SINK_INPUT(pa_idxset_first(sink->inputs, &iidx)); i; i = PA_SINK_INPUT(pa_idxset_next(sink->inputs, &iidx))) {
+ pa_cvolume si_volume;
+
+ si_volume = sink_volume;
+ pa_cvolume_remap(&si_volume, &sink->channel_map, &i->channel_map);
+ pa_sw_cvolume_multiply(&i->virtual_volume, &i->volume, &si_volume);
+ pa_log_debug("sink input = { id = %d, flat = %.2f, true = %.2f }",
+ i->index,
+ (double)pa_cvolume_avg(&i->virtual_volume)/PA_VOLUME_NORM,
+ (double)pa_cvolume_avg(&i->volume)/PA_VOLUME_NORM);
+ pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+ }
+}
+
+int pa__init(pa_module*m) {
+ struct userdata *u;
+
+ pa_assert(m);
+
+ u = pa_xnew(struct userdata, 1);
+ m->userdata = u;
+
+ u->sink_input_fixate_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
+ u->sink_input_set_volume_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], PA_HOOK_LATE, (pa_hook_cb_t) sink_input_set_volume_hook_callback, u);
+
+ u->subscription = pa_subscription_new(m->core, PA_SUBSCRIPTION_MASK_SINK, subscribe_callback, u);
+
+ return 0;
+}
+
+void pa__done(pa_module*m) {
+ struct userdata* u;
+
+ pa_assert(m);
+
+ if (!(u = m->userdata))
+ return;
+
+ if (u->subscription)
+ pa_subscription_free(u->subscription);
+
+ if (u->sink_input_set_volume_hook_slot)
+ pa_hook_slot_free(u->sink_input_set_volume_hook_slot);
+ if (u->sink_input_fixate_hook_slot)
+ pa_hook_slot_free(u->sink_input_fixate_hook_slot);
+
+ pa_xfree(u);
+}
diff --git a/src/modules/module-hal-detect.c b/src/modules/module-hal-detect.c
index caa7a1fa..c76a366c 100644
--- a/src/modules/module-hal-detect.c
+++ b/src/modules/module-hal-detect.c
@@ -108,7 +108,7 @@ static void hal_device_free(struct device* d) {
pa_xfree(d);
}
-static void hal_device_free_cb(void *d, PA_GCC_UNUSED void *data) {
+static void hal_device_free_cb(void *d, void *data) {
hal_device_free(d);
}
@@ -405,7 +405,7 @@ static void device_added_time_cb(pa_mainloop_api *ea, pa_time_event *ev, const s
dbus_error_init(&error);
if (!pa_hashmap_get(td->u->devices, td->udi)) {
- int b;
+ dbus_bool_t b;
struct device *d;
b = libhal_device_exists(td->u->context, td->udi, &error);
@@ -433,7 +433,7 @@ static void device_added_cb(LibHalContext *context, const char *udi) {
struct timeval tv;
struct timerdata *t;
struct userdata *u;
- int good = 0;
+ pa_bool_t good = FALSE;
pa_assert_se(u = libhal_ctx_get_user_data(context));
@@ -749,17 +749,17 @@ int pa__init(pa_module*m) {
}
if ((api = pa_modargs_get_value(ma, "api", NULL))) {
- int good = 0;
+ pa_bool_t good = FALSE;
#ifdef HAVE_ALSA
if (strcmp(api, CAPABILITY_ALSA) == 0) {
- good = 1;
+ good = TRUE;
api = CAPABILITY_ALSA;
}
#endif
#ifdef HAVE_OSS
if (strcmp(api, CAPABILITY_OSS) == 0) {
- good = 1;
+ good = TRUE;
api = CAPABILITY_OSS;
}
#endif
diff --git a/src/modules/module-jack-sink.c b/src/modules/module-jack-sink.c
index edc543a8..555cb825 100644
--- a/src/modules/module-jack-sink.c
+++ b/src/modules/module-jack-sink.c
@@ -130,12 +130,12 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
void *p;
pa_assert(offset > 0);
- nbytes = offset * pa_frame_size(&u->sink->sample_spec);
+ nbytes = (size_t) offset * pa_frame_size(&u->sink->sample_spec);
pa_sink_render_full(u->sink, nbytes, &chunk);
p = (uint8_t*) pa_memblock_acquire(chunk.memblock) + chunk.index;
- pa_deinterleave(p, u->buffer, u->channels, sizeof(float), offset);
+ pa_deinterleave(p, u->buffer, u->channels, sizeof(float), (unsigned) offset);
pa_memblock_release(chunk.memblock);
pa_memblock_unref(chunk.memblock);
@@ -149,10 +149,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
ss.channels = 1;
for (c = 0; c < u->channels; c++)
- pa_silence_memory(u->buffer[c], offset * pa_sample_size(&ss), &ss);
+ pa_silence_memory(u->buffer[c], (size_t) offset * pa_sample_size(&ss), &ss);
}
- u->frames_in_buffer = offset;
+ u->frames_in_buffer = (jack_nframes_t) offset;
u->saved_frame_time = * (jack_nframes_t*) data;
u->saved_frame_time_valid = TRUE;
@@ -342,7 +342,7 @@ int pa__init(pa_module*m) {
pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client));
- ss.channels = u->channels = channels;
+ u->channels = ss.channels = (uint8_t) channels;
ss.rate = jack_get_sample_rate(u->client);
ss.format = PA_SAMPLE_FLOAT32NE;
diff --git a/src/modules/module-jack-source.c b/src/modules/module-jack-source.c
index 03f9d15c..9eccbbfa 100644
--- a/src/modules/module-jack-source.c
+++ b/src/modules/module-jack-source.c
@@ -116,7 +116,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
if (u->source->thread_info.state == PA_SOURCE_RUNNING)
pa_source_post(u->source, chunk);
- u->saved_frame_time = offset;
+ u->saved_frame_time = (jack_nframes_t) offset;
u->saved_frame_time_valid = TRUE;
return 0;
@@ -309,7 +309,7 @@ int pa__init(pa_module*m) {
pa_log_info("Successfully connected as '%s'", jack_get_client_name(u->client));
- ss.channels = u->channels = channels;
+ u->channels = ss.channels = (uint8_t) channels;
ss.rate = jack_get_sample_rate(u->client);
ss.format = PA_SAMPLE_FLOAT32NE;
diff --git a/src/modules/module-ladspa-sink.c b/src/modules/module-ladspa-sink.c
index 23eeb340..a27ed712 100644
--- a/src/modules/module-ladspa-sink.c
+++ b/src/modules/module-ladspa-sink.c
@@ -187,7 +187,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t nbytes, pa_memchunk *chunk
pa_assert(tchunk.length > 0);
fs = pa_frame_size(&i->sample_spec);
- n = PA_MIN(tchunk.length, u->block_size) / fs;
+ n = (unsigned) (PA_MIN(tchunk.length, u->block_size) / fs);
pa_assert(n > 0);
@@ -359,6 +359,16 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
}
}
+/* Called from main context */
+static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
+ struct userdata *u;
+
+ pa_sink_input_assert_ref(i);
+ pa_assert_se(u = i->userdata);
+
+ return u->sink != dest;
+}
+
int pa__init(pa_module*m) {
struct userdata *u;
pa_sample_spec ss;
@@ -502,9 +512,9 @@ int pa__init(pa_module*m) {
u->block_size = pa_frame_align(pa_mempool_block_size_max(m->core->mempool), &ss);
- u->input = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size);
+ u->input = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
if (LADSPA_IS_INPLACE_BROKEN(d->Properties))
- u->output = (LADSPA_Data*) pa_xnew(uint8_t, u->block_size);
+ u->output = (LADSPA_Data*) pa_xnew(uint8_t, (unsigned) u->block_size);
else
u->output = u->input;
@@ -530,8 +540,8 @@ int pa__init(pa_module*m) {
char *k;
unsigned long h;
- u->control = pa_xnew(LADSPA_Data, n_control);
- use_default = pa_xnew(pa_bool_t, n_control);
+ u->control = pa_xnew(LADSPA_Data, (unsigned) n_control);
+ use_default = pa_xnew(pa_bool_t, (unsigned) n_control);
p = 0;
while ((k = pa_split(cdata, ",", &state)) && p < n_control) {
@@ -552,7 +562,7 @@ int pa__init(pa_module*m) {
pa_xfree(k);
use_default[p] = FALSE;
- u->control[p++] = f;
+ u->control[p++] = (LADSPA_Data) f;
}
/* The previous loop doesn't take the last control value into account
@@ -601,8 +611,8 @@ int pa__init(pa_module*m) {
upper = d->PortRangeHints[p].UpperBound;
if (LADSPA_IS_HINT_SAMPLE_RATE(hint)) {
- lower *= ss.rate;
- upper *= ss.rate;
+ lower *= (LADSPA_Data) ss.rate;
+ upper *= (LADSPA_Data) ss.rate;
}
switch (hint & LADSPA_HINT_DEFAULT_MASK) {
@@ -617,23 +627,23 @@ int pa__init(pa_module*m) {
case LADSPA_HINT_DEFAULT_LOW:
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
- u->control[h] = exp(log(lower) * 0.75 + log(upper) * 0.25);
+ u->control[h] = (LADSPA_Data) exp(log(lower) * 0.75 + log(upper) * 0.25);
else
- u->control[h] = lower * 0.75 + upper * 0.25;
+ u->control[h] = (LADSPA_Data) (lower * 0.75 + upper * 0.25);
break;
case LADSPA_HINT_DEFAULT_MIDDLE:
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
- u->control[h] = exp(log(lower) * 0.5 + log(upper) * 0.5);
+ u->control[h] = (LADSPA_Data) exp(log(lower) * 0.5 + log(upper) * 0.5);
else
- u->control[h] = lower * 0.5 + upper * 0.5;
+ u->control[h] = (LADSPA_Data) (lower * 0.5 + upper * 0.5);
break;
case LADSPA_HINT_DEFAULT_HIGH:
if (LADSPA_IS_HINT_LOGARITHMIC(hint))
- u->control[h] = exp(log(lower) * 0.25 + log(upper) * 0.75);
+ u->control[h] = (LADSPA_Data) exp(log(lower) * 0.25 + log(upper) * 0.75);
else
- u->control[h] = lower * 0.25 + upper * 0.75;
+ u->control[h] = (LADSPA_Data) (lower * 0.25 + upper * 0.75);
break;
case LADSPA_HINT_DEFAULT_0:
@@ -737,6 +747,7 @@ int pa__init(pa_module*m) {
u->sink_input->attach = sink_input_attach_cb;
u->sink_input->detach = sink_input_detach_cb;
u->sink_input->state_change = sink_input_state_change_cb;
+ u->sink_input->may_move_to = sink_input_may_move_to_cb;
u->sink_input->userdata = u;
pa_sink_put(u->sink);
diff --git a/src/modules/module-lirc.c b/src/modules/module-lirc.c
index f34f7be3..97e97dc7 100644
--- a/src/modules/module-lirc.c
+++ b/src/modules/module-lirc.c
@@ -65,7 +65,7 @@ struct userdata {
static int lirc_in_use = 0;
-static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) {
+static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
struct userdata *u = userdata;
char *name = NULL, *code = NULL;
@@ -122,7 +122,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
pa_log("Failed to get sink '%s'", u->sink_name);
else {
int i;
- pa_cvolume cv = *pa_sink_get_volume(s);
+ pa_cvolume cv = *pa_sink_get_volume(s, FALSE);
#define DELTA (PA_VOLUME_NORM/20)
@@ -159,7 +159,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
case MUTE_TOGGLE:
- pa_sink_set_mute(s, !pa_sink_get_mute(s));
+ pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE));
break;
case INVALID:
diff --git a/src/modules/module-mmkbd-evdev.c b/src/modules/module-mmkbd-evdev.c
index 7da77c0d..21f176a4 100644
--- a/src/modules/module-mmkbd-evdev.c
+++ b/src/modules/module-mmkbd-evdev.c
@@ -76,7 +76,7 @@ struct userdata {
pa_module *module;
};
-static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GCC_UNUSED int fd, pa_io_event_flags_t events, void*userdata) {
+static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
struct userdata *u = userdata;
pa_assert(io);
@@ -113,7 +113,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
pa_log("Failed to get sink '%s'", u->sink_name);
else {
int i;
- pa_cvolume cv = *pa_sink_get_volume(s);
+ pa_cvolume cv = *pa_sink_get_volume(s, FALSE);
#define DELTA (PA_VOLUME_NORM/20)
@@ -142,7 +142,7 @@ static void io_callback(pa_mainloop_api *io, PA_GCC_UNUSED pa_io_event *e, PA_GC
case MUTE_TOGGLE:
- pa_sink_set_mute(s, !pa_sink_get_mute(s));
+ pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE));
break;
case INVALID:
diff --git a/src/modules/module-native-protocol-fd.c b/src/modules/module-native-protocol-fd.c
index fa9c0e4f..f17f435a 100644
--- a/src/modules/module-native-protocol-fd.c
+++ b/src/modules/module-native-protocol-fd.c
@@ -48,7 +48,8 @@ static const char* const valid_modargs[] = {
int pa__init(pa_module*m) {
pa_iochannel *io;
pa_modargs *ma;
- int fd, r = -1;
+ int32_t fd;
+ int r = -1;
pa_native_options *options = NULL;
pa_assert(m);
@@ -63,18 +64,16 @@ int pa__init(pa_module*m) {
goto finish;
}
- options = pa_native_options_new();
- options->module = m;
- options->auth_anonymous = TRUE;
+ m->userdata = pa_native_protocol_get(m->core);
io = pa_iochannel_new(m->core->mainloop, fd, fd);
- m->userdata = pa_native_protocol_get(m->core);
+ options = pa_native_options_new();
+ options->module = m;
+ options->auth_anonymous = TRUE;
pa_native_protocol_connect(m->userdata, io, options);
- pa_native_options_unref(options);
-
r = 0;
finish:
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-oss.c b/src/modules/module-oss.c
index 15b1e956..23a32549 100644
--- a/src/modules/module-oss.c
+++ b/src/modules/module-oss.c
@@ -258,7 +258,7 @@ static int mmap_write(struct userdata *u) {
u->out_mmap_saved_nfrags = 0;
if (info.blocks > 0)
- mmap_fill_memblocks(u, info.blocks);
+ mmap_fill_memblocks(u, (unsigned) info.blocks);
return info.blocks;
}
@@ -336,7 +336,7 @@ static int mmap_read(struct userdata *u) {
u->in_mmap_saved_nfrags = 0;
if (info.blocks > 0) {
- mmap_post_memblocks(u, info.blocks);
+ mmap_post_memblocks(u, (unsigned) info.blocks);
mmap_clear_memblocks(u, u->in_nfrags/2);
}
@@ -356,12 +356,12 @@ static pa_usec_t mmap_sink_get_latency(struct userdata *u) {
u->out_mmap_saved_nfrags += info.blocks;
- bpos = ((u->out_mmap_current + u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size;
+ bpos = ((u->out_mmap_current + (unsigned) u->out_mmap_saved_nfrags) * u->out_fragment_size) % u->out_hwbuf_size;
if (bpos <= (size_t) info.ptr)
- n = u->out_hwbuf_size - (info.ptr - bpos);
+ n = u->out_hwbuf_size - ((size_t) info.ptr - bpos);
else
- n = bpos - info.ptr;
+ n = bpos - (size_t) info.ptr;
/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->out_fragment_size, u->out_fragments); */
@@ -380,12 +380,12 @@ static pa_usec_t mmap_source_get_latency(struct userdata *u) {
}
u->in_mmap_saved_nfrags += info.blocks;
- bpos = ((u->in_mmap_current + u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size;
+ bpos = ((u->in_mmap_current + (unsigned) u->in_mmap_saved_nfrags) * u->in_fragment_size) % u->in_hwbuf_size;
if (bpos <= (size_t) info.ptr)
- n = info.ptr - bpos;
+ n = (size_t) info.ptr - bpos;
else
- n = u->in_hwbuf_size - bpos + info.ptr;
+ n = u->in_hwbuf_size - bpos + (size_t) info.ptr;
/* pa_log("n = %u, bpos = %u, ptr = %u, total=%u, fragsize = %u, n_frags = %u\n", n, bpos, (unsigned) info.ptr, total, u->in_fragment_size, u->in_fragments); */
@@ -404,7 +404,7 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) {
pa_log_info("Device doesn't support SNDCTL_DSP_GETODELAY: %s", pa_cstrerror(errno));
u->use_getodelay = 0;
} else
- r = pa_bytes_to_usec(arg, &u->sink->sample_spec);
+ r = pa_bytes_to_usec((size_t) arg, &u->sink->sample_spec);
}
@@ -415,7 +415,7 @@ static pa_usec_t io_sink_get_latency(struct userdata *u) {
pa_log_info("Device doesn't support SNDCTL_DSP_GETOSPACE: %s", pa_cstrerror(errno));
u->use_getospace = 0;
} else
- r = pa_bytes_to_usec(info.bytes, &u->sink->sample_spec);
+ r = pa_bytes_to_usec((size_t) info.bytes, &u->sink->sample_spec);
}
if (u->memchunk.memblock)
@@ -437,7 +437,7 @@ static pa_usec_t io_source_get_latency(struct userdata *u) {
pa_log_info("Device doesn't support SNDCTL_DSP_GETISPACE: %s", pa_cstrerror(errno));
u->use_getispace = 0;
} else
- r = pa_bytes_to_usec(info.bytes, &u->source->sample_spec);
+ r = pa_bytes_to_usec((size_t) info.bytes, &u->source->sample_spec);
}
return r;
@@ -528,8 +528,9 @@ static int unsuspend(struct userdata *u) {
if ((u->fd = pa_oss_open(u->device_name, &m, NULL)) < 0) {
pa_log_warn("Resume failed, device busy (%s)", pa_cstrerror(errno));
return -1;
+ }
- if (m != u->mode)
+ if (m != u->mode) {
pa_log_warn("Resume failed, couldn't open device with original access mode.");
goto fail;
}
@@ -859,7 +860,7 @@ static int source_set_volume(pa_source *s) {
static void thread_func(void *userdata) {
struct userdata *u = userdata;
int write_type = 0, read_type = 0;
- unsigned short revents = 0;
+ short revents = 0;
pa_assert(u);
@@ -898,7 +899,7 @@ static void thread_func(void *userdata) {
ssize_t l;
pa_bool_t loop = FALSE, work_done = FALSE;
- l = u->out_fragment_size;
+ l = (ssize_t) u->out_fragment_size;
if (u->use_getospace) {
audio_buf_info info;
@@ -919,14 +920,14 @@ static void thread_func(void *userdata) {
/* Round down to multiples of the fragment size,
* because OSS needs that (at least some versions
* do) */
- l = (l/u->out_fragment_size) * u->out_fragment_size;
+ l = (l/(ssize_t) u->out_fragment_size) * (ssize_t) u->out_fragment_size;
/* Hmm, so poll() signalled us that we can read
* something, but GETOSPACE told us there was nothing?
* Hmm, make the best of it, try to read some data, to
* avoid spinning forever. */
if (l <= 0 && (revents & POLLOUT)) {
- l = u->out_fragment_size;
+ l = (ssize_t) u->out_fragment_size;
loop = FALSE;
}
@@ -935,7 +936,7 @@ static void thread_func(void *userdata) {
ssize_t t;
if (u->memchunk.length <= 0)
- pa_sink_render(u->sink, l, &u->memchunk);
+ pa_sink_render(u->sink, (size_t) l, &u->memchunk);
pa_assert(u->memchunk.length > 0);
@@ -965,8 +966,8 @@ static void thread_func(void *userdata) {
} else {
- u->memchunk.index += t;
- u->memchunk.length -= t;
+ u->memchunk.index += (size_t) t;
+ u->memchunk.length -= (size_t) t;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@@ -1009,7 +1010,7 @@ static void thread_func(void *userdata) {
pa_memchunk memchunk;
pa_bool_t loop = FALSE, work_done = FALSE;
- l = u->in_fragment_size;
+ l = (ssize_t) u->in_fragment_size;
if (u->use_getispace) {
audio_buf_info info;
@@ -1023,15 +1024,16 @@ static void thread_func(void *userdata) {
}
}
- l = (l/u->in_fragment_size) * u->in_fragment_size;
+ l = (l/(ssize_t) u->in_fragment_size) * (ssize_t) u->in_fragment_size;
if (l <= 0 && (revents & POLLIN)) {
- l = u->in_fragment_size;
+ l = (ssize_t) u->in_fragment_size;
loop = FALSE;
}
while (l > 0) {
- ssize_t t, k;
+ ssize_t t;
+ size_t k;
pa_assert(l > 0);
@@ -1039,8 +1041,8 @@ static void thread_func(void *userdata) {
k = pa_memblock_get_length(memchunk.memblock);
- if (k > l)
- k = l;
+ if (k > (size_t) l)
+ k = (size_t) l;
k = (k/u->frame_size)*u->frame_size;
@@ -1071,7 +1073,7 @@ static void thread_func(void *userdata) {
} else {
memchunk.index = 0;
- memchunk.length = t;
+ memchunk.length = (size_t) t;
pa_source_post(u->source, &memchunk);
pa_memblock_unref(memchunk.memblock);
@@ -1099,9 +1101,9 @@ static void thread_func(void *userdata) {
pa_assert(u->fd >= 0);
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
- pollfd->events =
- ((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) |
- ((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0);
+ pollfd->events = (short)
+ (((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) |
+ ((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0));
}
/* Hmm, nothing to do. Let's sleep */
@@ -1179,10 +1181,10 @@ int pa__init(pa_module*m) {
goto fail;
}
- nfrags = m->core->default_n_fragments;
- frag_size = pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss);
+ nfrags = (int) m->core->default_n_fragments;
+ frag_size = (int) pa_usec_to_bytes(m->core->default_fragment_size_msec*1000, &ss);
if (frag_size <= 0)
- frag_size = pa_frame_size(&ss);
+ frag_size = (int) pa_frame_size(&ss);
if (pa_modargs_get_value_s32(ma, "fragments", &nfrags) < 0 || pa_modargs_get_value_s32(ma, "fragment_size", &frag_size) < 0) {
pa_log("Failed to parse fragments arguments");
@@ -1238,8 +1240,8 @@ int pa__init(pa_module*m) {
u->mode = mode;
u->frame_size = pa_frame_size(&ss);
u->device_name = pa_xstrdup(dev);
- u->in_nfrags = u->out_nfrags = u->nfrags = nfrags;
- u->out_fragment_size = u->in_fragment_size = u->frag_size = frag_size;
+ u->in_nfrags = u->out_nfrags = (uint32_t) (u->nfrags = nfrags);
+ u->out_fragment_size = u->in_fragment_size = (uint32_t) (u->frag_size = frag_size);
u->use_mmap = use_mmap;
u->rtpoll = pa_rtpoll_new();
pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
@@ -1248,15 +1250,15 @@ int pa__init(pa_module*m) {
if (ioctl(fd, SNDCTL_DSP_GETISPACE, &info) >= 0) {
pa_log_info("Input -- %u fragments of size %u.", info.fragstotal, info.fragsize);
- u->in_fragment_size = info.fragsize;
- u->in_nfrags = info.fragstotal;
+ u->in_fragment_size = (uint32_t) info.fragsize;
+ u->in_nfrags = (uint32_t) info.fragstotal;
u->use_getispace = TRUE;
}
if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) >= 0) {
pa_log_info("Output -- %u fragments of size %u.", info.fragstotal, info.fragsize);
- u->out_fragment_size = info.fragsize;
- u->out_nfrags = info.fragstotal;
+ u->out_fragment_size = (uint32_t) info.fragsize;
+ u->out_nfrags = (uint32_t) info.fragstotal;
u->use_getospace = TRUE;
}
diff --git a/src/modules/module-pipe-sink.c b/src/modules/module-pipe-sink.c
index f389cd06..ae230b2c 100644
--- a/src/modules/module-pipe-sink.c
+++ b/src/modules/module-pipe-sink.c
@@ -145,8 +145,8 @@ static int process_render(struct userdata *u) {
} else {
- u->memchunk.index += l;
- u->memchunk.length -= l;
+ u->memchunk.index += (size_t) l;
+ u->memchunk.length -= (size_t) l;
if (u->memchunk.length <= 0) {
pa_memblock_unref(u->memchunk.memblock);
@@ -189,7 +189,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
- pollfd->events = u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0;
+ pollfd->events = (short) (u->sink->thread_info.state == PA_SINK_RUNNING ? POLLOUT : 0);
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;
diff --git a/src/modules/module-pipe-source.c b/src/modules/module-pipe-source.c
index b0de34ca..25151d95 100644
--- a/src/modules/module-pipe-source.c
+++ b/src/modules/module-pipe-source.c
@@ -135,9 +135,9 @@ static void thread_func(void *userdata) {
} else {
- u->memchunk.length = l;
+ u->memchunk.length = (size_t) l;
pa_source_post(u->source, &u->memchunk);
- u->memchunk.index += l;
+ u->memchunk.index += (size_t) l;
if (u->memchunk.index >= pa_memblock_get_length(u->memchunk.memblock)) {
pa_memblock_unref(u->memchunk.memblock);
@@ -149,7 +149,7 @@ static void thread_func(void *userdata) {
}
/* Hmm, nothing to do. Let's sleep */
- pollfd->events = u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0;
+ pollfd->events = (short) (u->source->thread_info.state == PA_SOURCE_RUNNING ? POLLIN : 0);
if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
goto fail;
diff --git a/src/modules/module-protocol-stub.c b/src/modules/module-protocol-stub.c
index 8136c6fc..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"
@@ -260,7 +260,7 @@ int pa__init(pa_module*m) {
goto fail;
}
- u = pa_xnew0(struct userdata, 1);
+ m->userdata = u = pa_xnew0(struct userdata, 1);
u->module = m;
#if defined(USE_PROTOCOL_SIMPLE)
@@ -299,11 +299,11 @@ int pa__init(pa_module*m) {
listen_on = pa_modargs_get_value(ma, "listen", NULL);
if (listen_on) {
- u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE);
- u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, port, TCPWRAP_SERVICE);
+ u->socket_server_ipv6 = pa_socket_server_new_ipv6_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE);
+ u->socket_server_ipv4 = pa_socket_server_new_ipv4_string(m->core->mainloop, listen_on, (uint16_t) port, TCPWRAP_SERVICE);
} else {
- u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, port, TCPWRAP_SERVICE);
- u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, port, TCPWRAP_SERVICE);
+ u->socket_server_ipv6 = pa_socket_server_new_ipv6_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE);
+ u->socket_server_ipv4 = pa_socket_server_new_ipv4_any(m->core->mainloop, (uint16_t) port, TCPWRAP_SERVICE);
}
if (!u->socket_server_ipv4 && !u->socket_server_ipv6)
@@ -327,7 +327,7 @@ int pa__init(pa_module*m) {
/* This socket doesn't reside in our own runtime dir but in
* /tmp/.esd/, hence we have to create the dir first */
- if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755 : 0700, (uid_t)-1, (gid_t)-1) < 0) {
+ if (pa_make_secure_parent_dir(u->socket_path, pa_in_system_mode() ? 0755U : 0700U, (uid_t)-1, (gid_t)-1) < 0) {
pa_log("Failed to create socket directory '%s': %s\n", u->socket_path, pa_cstrerror(errno));
goto fail;
}
@@ -368,8 +368,6 @@ int pa__init(pa_module*m) {
# endif
#endif
- m->userdata = u;
-
if (ma)
pa_modargs_free(ma);
@@ -390,7 +388,8 @@ void pa__done(pa_module*m) {
pa_assert(m);
- u = m->userdata;
+ if (!(u = m->userdata))
+ return;
#if defined(USE_PROTOCOL_SIMPLE)
if (u->simple_protocol) {
diff --git a/src/modules/module-raop-discover.c b/src/modules/module-raop-discover.c
new file mode 100644
index 00000000..3706d921
--- /dev/null
+++ b/src/modules/module-raop-discover.c
@@ -0,0 +1,380 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2008 Colin Guthrie
+
+ 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 <unistd.h>
+
+#include <avahi-client/client.h>
+#include <avahi-client/lookup.h>
+#include <avahi-common/alternative.h>
+#include <avahi-common/error.h>
+#include <avahi-common/domain.h>
+#include <avahi-common/malloc.h>
+
+#include <pulse/xmalloc.h>
+#include <pulse/util.h>
+
+#include <pulsecore/sink.h>
+#include <pulsecore/source.h>
+#include <pulsecore/native-common.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/core-subscribe.h>
+#include <pulsecore/hashmap.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/namereg.h>
+#include <pulsecore/avahi-wrap.h>
+
+#include "module-raop-discover-symdef.h"
+
+PA_MODULE_AUTHOR("Colin Guthrie");
+PA_MODULE_DESCRIPTION("mDNS/DNS-SD Service Discovery of Airtunes");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(TRUE);
+
+#define SERVICE_TYPE_SINK "_raop._tcp"
+
+static const char* const valid_modargs[] = {
+ NULL
+};
+
+struct tunnel {
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
+ char *name, *type, *domain;
+ uint32_t module_index;
+};
+
+struct userdata {
+ pa_core *core;
+ pa_module *module;
+ AvahiPoll *avahi_poll;
+ AvahiClient *client;
+ AvahiServiceBrowser *sink_browser;
+
+ pa_hashmap *tunnels;
+};
+
+static unsigned tunnel_hash(const void *p) {
+ const struct tunnel *t = p;
+
+ return
+ (unsigned) t->interface +
+ (unsigned) t->protocol +
+ pa_idxset_string_hash_func(t->name) +
+ pa_idxset_string_hash_func(t->type) +
+ pa_idxset_string_hash_func(t->domain);
+}
+
+static int tunnel_compare(const void *a, const void *b) {
+ const struct tunnel *ta = a, *tb = b;
+ int r;
+
+ if (ta->interface != tb->interface)
+ return 1;
+ if (ta->protocol != tb->protocol)
+ return 1;
+ if ((r = strcmp(ta->name, tb->name)))
+ return r;
+ if ((r = strcmp(ta->type, tb->type)))
+ return r;
+ if ((r = strcmp(ta->domain, tb->domain)))
+ return r;
+
+ return 0;
+}
+
+static struct tunnel *tunnel_new(
+ AvahiIfIndex interface, AvahiProtocol protocol,
+ const char *name, const char *type, const char *domain) {
+
+ struct tunnel *t;
+ t = pa_xnew(struct tunnel, 1);
+ t->interface = interface;
+ t->protocol = protocol;
+ t->name = pa_xstrdup(name);
+ t->type = pa_xstrdup(type);
+ t->domain = pa_xstrdup(domain);
+ t->module_index = PA_IDXSET_INVALID;
+ return t;
+}
+
+static void tunnel_free(struct tunnel *t) {
+ pa_assert(t);
+ pa_xfree(t->name);
+ pa_xfree(t->type);
+ pa_xfree(t->domain);
+ pa_xfree(t);
+}
+
+static void resolver_cb(
+ AvahiServiceResolver *r,
+ AvahiIfIndex interface, AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name, const char *type, const char *domain,
+ const char *host_name, const AvahiAddress *a, uint16_t port,
+ AvahiStringList *txt,
+ AvahiLookupResultFlags flags,
+ void *userdata) {
+
+ struct userdata *u = userdata;
+ struct tunnel *tnl;
+
+ pa_assert(u);
+
+ tnl = tunnel_new(interface, protocol, name, type, domain);
+
+ if (event != AVAHI_RESOLVER_FOUND)
+ pa_log("Resolving of '%s' failed: %s", name, avahi_strerror(avahi_client_errno(u->client)));
+ else {
+ char *device = NULL, *dname, *vname, *args;
+ char at[AVAHI_ADDRESS_STR_MAX];
+ AvahiStringList *l;
+ pa_module *m;
+
+ for (l = txt; l; l = l->next) {
+ char *key, *value;
+ pa_assert_se(avahi_string_list_get_pair(l, &key, &value, NULL) == 0);
+
+ pa_log_debug("Found key: '%s' with value: '%s'", key, value);
+ if (strcmp(key, "device") == 0) {
+ pa_xfree(device);
+ device = value;
+ value = NULL;
+ }
+ avahi_free(key);
+ avahi_free(value);
+ }
+
+ if (device)
+ dname = pa_sprintf_malloc("airtunes.%s.%s", host_name, device);
+ else
+ dname = pa_sprintf_malloc("airtunes.%s", host_name);
+
+ if (!(vname = pa_namereg_make_valid_name(dname))) {
+ pa_log("Cannot construct valid device name from '%s'.", dname);
+ avahi_free(device);
+ pa_xfree(dname);
+ goto finish;
+ }
+ pa_xfree(dname);
+
+ /*
+ TODO: allow this syntax of server name in things....
+ args = pa_sprintf_malloc("server=[%s]:%u "
+ "sink_name=%s",
+ avahi_address_snprint(at, sizeof(at), a), port,
+ vname);*/
+ args = pa_sprintf_malloc("server=%s "
+ "sink_name=%s",
+ avahi_address_snprint(at, sizeof(at), a),
+ vname);
+
+ pa_log_debug("Loading module-raop-sink with arguments '%s'", args);
+
+ if ((m = pa_module_load(u->core, "module-raop-sink", args))) {
+ tnl->module_index = m->index;
+ pa_hashmap_put(u->tunnels, tnl, tnl);
+ tnl = NULL;
+ }
+
+ pa_xfree(vname);
+ pa_xfree(args);
+ avahi_free(device);
+ }
+
+finish:
+
+ avahi_service_resolver_free(r);
+
+ if (tnl)
+ tunnel_free(tnl);
+}
+
+static void browser_cb(
+ AvahiServiceBrowser *b,
+ AvahiIfIndex interface, AvahiProtocol protocol,
+ AvahiBrowserEvent event,
+ const char *name, const char *type, const char *domain,
+ AvahiLookupResultFlags flags,
+ void *userdata) {
+
+ struct userdata *u = userdata;
+ struct tunnel *t;
+
+ pa_assert(u);
+
+ if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
+ return;
+
+ t = tunnel_new(interface, protocol, name, type, domain);
+
+ if (event == AVAHI_BROWSER_NEW) {
+
+ if (!pa_hashmap_get(u->tunnels, t))
+ if (!(avahi_service_resolver_new(u->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, 0, resolver_cb, u)))
+ pa_log("avahi_service_resolver_new() failed: %s", avahi_strerror(avahi_client_errno(u->client)));
+
+ /* We ignore the returned resolver object here, since the we don't
+ * need to attach any special data to it, and we can still destory
+ * it from the callback */
+
+ } else if (event == AVAHI_BROWSER_REMOVE) {
+ struct tunnel *t2;
+
+ if ((t2 = pa_hashmap_get(u->tunnels, t))) {
+ pa_module_unload_by_index(u->core, t2->module_index, TRUE);
+ pa_hashmap_remove(u->tunnels, t2);
+ tunnel_free(t2);
+ }
+ }
+
+ tunnel_free(t);
+}
+
+static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) {
+ struct userdata *u = userdata;
+
+ pa_assert(c);
+ pa_assert(u);
+
+ u->client = c;
+
+ switch (state) {
+ case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_S_RUNNING:
+ case AVAHI_CLIENT_S_COLLISION:
+
+ if (!u->sink_browser) {
+
+ if (!(u->sink_browser = avahi_service_browser_new(
+ c,
+ AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ SERVICE_TYPE_SINK,
+ NULL,
+ 0,
+ browser_cb, u))) {
+
+ pa_log("avahi_service_browser_new() failed: %s", avahi_strerror(avahi_client_errno(c)));
+ pa_module_unload_request(u->module, TRUE);
+ }
+ }
+
+ break;
+
+ case AVAHI_CLIENT_FAILURE:
+ if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) {
+ int error;
+
+ pa_log_debug("Avahi daemon disconnected.");
+
+ if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) {
+ pa_log("avahi_client_new() failed: %s", avahi_strerror(error));
+ pa_module_unload_request(u->module, TRUE);
+ }
+ }
+
+ /* Fall through */
+
+ case AVAHI_CLIENT_CONNECTING:
+
+ if (u->sink_browser) {
+ avahi_service_browser_free(u->sink_browser);
+ u->sink_browser = NULL;
+ }
+
+ break;
+
+ default: ;
+ }
+}
+
+int pa__init(pa_module*m) {
+
+ struct userdata *u;
+ pa_modargs *ma = NULL;
+ int error;
+
+ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+ pa_log("Failed to parse module arguments.");
+ goto fail;
+ }
+
+ m->userdata = u = pa_xnew(struct userdata, 1);
+ u->core = m->core;
+ u->module = m;
+ u->sink_browser = NULL;
+
+ u->tunnels = pa_hashmap_new(tunnel_hash, tunnel_compare);
+
+ u->avahi_poll = pa_avahi_poll_new(m->core->mainloop);
+
+ if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) {
+ pa_log("pa_avahi_client_new() failed: %s", avahi_strerror(error));
+ goto fail;
+ }
+
+ pa_modargs_free(ma);
+
+ return 0;
+
+fail:
+ pa__done(m);
+
+ if (ma)
+ pa_modargs_free(ma);
+
+ return -1;
+}
+
+void pa__done(pa_module*m) {
+ struct userdata*u;
+ pa_assert(m);
+
+ if (!(u = m->userdata))
+ return;
+
+ if (u->client)
+ avahi_client_free(u->client);
+
+ if (u->avahi_poll)
+ pa_avahi_poll_free(u->avahi_poll);
+
+ if (u->tunnels) {
+ struct tunnel *t;
+
+ while ((t = pa_hashmap_steal_first(u->tunnels))) {
+ pa_module_unload_by_index(u->core, t->module_index, TRUE);
+ tunnel_free(t);
+ }
+
+ pa_hashmap_free(u->tunnels, NULL, NULL);
+ }
+
+ pa_xfree(u);
+}
diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c
new file mode 100644
index 00000000..62f0a73c
--- /dev/null
+++ b/src/modules/module-raop-sink.c
@@ -0,0 +1,675 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2004-2006 Lennart Poettering
+ Copyright 2008 Colin Guthrie
+
+ 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 <stdlib.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_LINUX_SOCKIOS_H
+#include <linux/sockios.h>
+#endif
+
+#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/iochannel.h>
+#include <pulsecore/sink.h>
+#include <pulsecore/module.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/modargs.h>
+#include <pulsecore/log.h>
+#include <pulsecore/socket-client.h>
+#include <pulsecore/authkey.h>
+#include <pulsecore/thread-mq.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/time-smoother.h>
+#include <pulsecore/rtclock.h>
+#include <pulsecore/socket-util.h>
+
+#include "module-raop-sink-symdef.h"
+#include "rtp.h"
+#include "sdp.h"
+#include "sap.h"
+#include "raop_client.h"
+
+PA_MODULE_AUTHOR("Colin Guthrie");
+PA_MODULE_DESCRIPTION("RAOP Sink (Apple Airtunes)");
+PA_MODULE_VERSION(PACKAGE_VERSION);
+PA_MODULE_LOAD_ONCE(FALSE);
+PA_MODULE_USAGE(
+ "sink_name=<name for the sink> "
+ "server=<address> "
+ "format=<sample format> "
+ "channels=<number of channels> "
+ "rate=<sample rate>");
+
+#define DEFAULT_SINK_NAME "airtunes"
+
+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;
+
+ pa_memchunk raw_memchunk;
+ pa_memchunk encoded_memchunk;
+
+ void *write_data;
+ size_t write_length, write_index;
+
+ void *read_data;
+ size_t read_length, read_index;
+
+ pa_usec_t latency;
+
+ pa_volume_t volume;
+ pa_bool_t muted;
+
+ /*esd_format_t format;*/
+ int32_t rate;
+
+ pa_smoother *smoother;
+ int fd;
+
+ int64_t offset;
+ int64_t encoding_overhead;
+ int32_t next_encoding_overhead;
+ double encoding_ratio;
+
+ pa_raop_client *raop;
+
+ size_t block_size;
+};
+
+static const char* const valid_modargs[] = {
+ "server",
+ "rate",
+ "format",
+ "channels",
+ "sink_name",
+ NULL
+};
+
+enum {
+ SINK_MESSAGE_PASS_SOCKET = PA_SINK_MESSAGE_MAX,
+ SINK_MESSAGE_RIP_SOCKET
+};
+
+static void on_connection(PA_GCC_UNUSED int fd, void*userdata) {
+ struct userdata *u = userdata;
+ pa_assert(u);
+
+ pa_assert(u->fd < 0);
+ u->fd = fd;
+
+ /* Set the initial volume */
+ pa_raop_client_set_volume(u->raop, u->volume);
+
+ pa_log_debug("Connection authenticated, handing fd to IO thread...");
+
+ pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_PASS_SOCKET, NULL, 0, NULL, NULL);
+}
+
+static void on_close(void*userdata) {
+ struct userdata *u = userdata;
+ pa_assert(u);
+
+ pa_log_debug("Connection closed, informing IO thread...");
+
+ pa_asyncmsgq_post(u->thread_mq.inq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_RIP_SOCKET, NULL, 0, NULL, NULL);
+}
+
+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;
+
+ 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());
+
+ /* Issue a FLUSH if we are connected */
+ if (u->fd >= 0) {
+ pa_raop_flush(u->raop);
+ }
+ 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());
+
+ /* The connection can be closed when idle, so check to
+ see if we need to reestablish it */
+ if (u->fd < 0)
+ pa_raop_connect(u->raop);
+ else
+ pa_raop_flush(u->raop);
+ }
+
+ 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 - u->encoding_overhead + (u->encoded_memchunk.length / u->encoding_ratio)), &u->sink->sample_spec);
+
+ *((pa_usec_t*) data) = w > r ? w - r : 0;
+ break;
+ }
+
+ case SINK_MESSAGE_PASS_SOCKET: {
+ struct pollfd *pollfd;
+
+ pa_assert(!u->rtpoll_item);
+
+ 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->fd;
+ pollfd->events = POLLOUT;
+ /*pollfd->events = */pollfd->revents = 0;
+
+ if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
+ /* Our stream has been suspended so we just flush it.... */
+ pa_raop_flush(u->raop);
+ }
+ return 0;
+ }
+
+ case SINK_MESSAGE_RIP_SOCKET: {
+ pa_assert(u->fd >= 0);
+
+ pa_close(u->fd);
+ u->fd = -1;
+
+ if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
+
+ pa_log_debug("RTSP control connection closed, but we're suspended so let's not worry about it... we'll open it again later");
+
+ if (u->rtpoll_item)
+ pa_rtpoll_item_free(u->rtpoll_item);
+ u->rtpoll_item = NULL;
+ } else {
+ /* Quesiton: is this valid here: or should we do some sort of:
+ return pa_sink_process_msg(PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL);
+ ?? */
+ pa_module_unload_request(u->module, TRUE);
+ }
+ return 0;
+ }
+ }
+
+ return pa_sink_process_msg(o, code, data, offset, chunk);
+}
+
+static int sink_get_volume_cb(pa_sink *s) {
+ struct userdata *u = s->userdata;
+ int i;
+
+ pa_assert(u);
+
+ for (i = 0; i < s->sample_spec.channels; i++) {
+ s->volume.values[i] = u->volume;
+ }
+
+ return 0;
+}
+
+static int sink_set_volume_cb(pa_sink *s) {
+ struct userdata *u = s->userdata;
+ int rv;
+
+ pa_assert(u);
+
+ /* If we're muted, we fake it */
+ if (u->muted)
+ return 0;
+
+ pa_assert(s->sample_spec.channels > 0);
+
+ /* Avoid pointless volume sets */
+ if (u->volume == s->volume.values[0])
+ return 0;
+
+ rv = pa_raop_client_set_volume(u->raop, s->volume.values[0]);
+ if (0 == rv)
+ u->volume = s->volume.values[0];
+
+ return rv;
+}
+
+static int sink_get_mute_cb(pa_sink *s) {
+ struct userdata *u = s->userdata;
+
+ pa_assert(u);
+
+ s->muted = u->muted;
+ return 0;
+}
+
+static int sink_set_mute_cb(pa_sink *s) {
+ struct userdata *u = s->userdata;
+ int rv;
+
+ pa_assert(u);
+
+ rv = pa_raop_client_set_volume(u->raop, (s->muted ? PA_VOLUME_MUTED : u->volume));
+ u->muted = s->muted;
+ return rv;
+}
+
+static void thread_func(void *userdata) {
+ struct userdata *u = userdata;
+ int write_type = 0;
+ pa_memchunk silence;
+ uint32_t silence_overhead = 0;
+ double silence_ratio = 0;
+
+ pa_assert(u);
+
+ pa_log_debug("Thread starting up");
+
+ pa_thread_mq_install(&u->thread_mq);
+ pa_rtpoll_install(u->rtpoll);
+
+ pa_smoother_set_time_offset(u->smoother, pa_rtclock_usec());
+
+ /* Create a chunk of memory that is our encoded silence sample. */
+ pa_memchunk_reset(&silence);
+
+ for (;;) {
+ int ret;
+
+ if (PA_SINK_IS_OPENED(u->sink->thread_info.state))
+ if (u->sink->thread_info.rewind_requested)
+ pa_sink_process_rewind(u->sink, 0);
+
+ if (u->rtpoll_item) {
+ struct pollfd *pollfd;
+ pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+
+ /* Render some data and write it to the fifo */
+ if (/*PA_SINK_IS_OPENED(u->sink->thread_info.state) && */pollfd->revents) {
+ pa_usec_t usec;
+ int64_t n;
+ void *p;
+
+ if (!silence.memblock) {
+ pa_memchunk silence_tmp;
+
+ pa_memchunk_reset(&silence_tmp);
+ silence_tmp.memblock = pa_memblock_new(u->core->mempool, 4096);
+ silence_tmp.length = 4096;
+ p = pa_memblock_acquire(silence_tmp.memblock);
+ memset(p, 0, 4096);
+ pa_memblock_release(silence_tmp.memblock);
+ pa_raop_client_encode_sample(u->raop, &silence_tmp, &silence);
+ pa_assert(0 == silence_tmp.length);
+ silence_overhead = silence_tmp.length - 4096;
+ silence_ratio = silence_tmp.length / 4096;
+ pa_memblock_unref(silence_tmp.memblock);
+ }
+
+ for (;;) {
+ ssize_t l;
+
+ if (u->encoded_memchunk.length <= 0) {
+ if (u->encoded_memchunk.memblock)
+ pa_memblock_unref(u->encoded_memchunk.memblock);
+ if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+ size_t rl;
+
+ /* We render real data */
+ if (u->raw_memchunk.length <= 0) {
+ if (u->raw_memchunk.memblock)
+ pa_memblock_unref(u->raw_memchunk.memblock);
+ pa_memchunk_reset(&u->raw_memchunk);
+
+ /* Grab unencoded data */
+ pa_sink_render(u->sink, u->block_size, &u->raw_memchunk);
+ }
+ pa_assert(u->raw_memchunk.length > 0);
+
+ /* Encode it */
+ rl = u->raw_memchunk.length;
+ u->encoding_overhead += u->next_encoding_overhead;
+ pa_raop_client_encode_sample(u->raop, &u->raw_memchunk, &u->encoded_memchunk);
+ u->next_encoding_overhead = (u->encoded_memchunk.length - (rl - u->raw_memchunk.length));
+ u->encoding_ratio = u->encoded_memchunk.length / (rl - u->raw_memchunk.length);
+ } else {
+ /* We render some silence into our memchunk */
+ memcpy(&u->encoded_memchunk, &silence, sizeof(pa_memchunk));
+ pa_memblock_ref(silence.memblock);
+
+ /* Calculate/store some values to be used with the smoother */
+ u->next_encoding_overhead = silence_overhead;
+ u->encoding_ratio = silence_ratio;
+ }
+ }
+ pa_assert(u->encoded_memchunk.length > 0);
+
+ p = pa_memblock_acquire(u->encoded_memchunk.memblock);
+ l = pa_write(u->fd, (uint8_t*) p + u->encoded_memchunk.index, u->encoded_memchunk.length, &write_type);
+ pa_memblock_release(u->encoded_memchunk.memblock);
+
+ pa_assert(l != 0);
+
+ if (l < 0) {
+
+ if (errno == EINTR)
+ continue;
+ else if (errno == EAGAIN) {
+
+ /* OK, we filled all socket buffers up
+ * now. */
+ goto filled_up;
+
+ } else {
+ pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno));
+ goto fail;
+ }
+
+ } else {
+ u->offset += l;
+
+ u->encoded_memchunk.index += l;
+ u->encoded_memchunk.length -= l;
+
+ pollfd->revents = 0;
+
+ if (u->encoded_memchunk.length > 0) {
+ /* we've completely written the encoded data, so update our overhead */
+ u->encoding_overhead += u->next_encoding_overhead;
+
+ /* OK, we wrote less that we asked for,
+ * hence we can assume that the socket
+ * buffers are full now */
+ goto filled_up;
+ }
+ }
+ }
+
+ filled_up:
+
+ /* At this spot we know that the socket buffers are
+ * fully filled up. This is the best time to estimate
+ * the playback position of the server */
+
+ n = u->offset - u->encoding_overhead;
+
+#ifdef SIOCOUTQ
+ {
+ int l;
+ if (ioctl(u->fd, SIOCOUTQ, &l) >= 0 && l > 0)
+ n -= (l / u->encoding_ratio);
+ }
+#endif
+
+ 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 */
+ pollfd->events = POLLOUT; /*PA_SINK_IS_OPENED(u->sink->thread_info.state) ? POLLOUT : 0;*/
+ }
+
+ if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
+ goto fail;
+
+ if (ret == 0)
+ goto finish;
+
+ if (u->rtpoll_item) {
+ struct pollfd* pollfd;
+
+ pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
+
+ if (pollfd->revents & ~POLLOUT) {
+ if (u->sink->thread_info.state != PA_SINK_SUSPENDED) {
+ pa_log("FIFO shutdown.");
+ goto fail;
+ }
+
+ /* We expect this to happen on occasion if we are not sending data.
+ It's perfectly natural and normal and natural */
+ if (u->rtpoll_item)
+ pa_rtpoll_item_free(u->rtpoll_item);
+ u->rtpoll_item = NULL;
+ }
+ }
+ }
+
+fail:
+ /* If this was no regular exit from the loop we have to continue
+ * processing messages until we received PA_MESSAGE_SHUTDOWN */
+ 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:
+ if (silence.memblock)
+ pa_memblock_unref(silence.memblock);
+ pa_log_debug("Thread shutting down");
+}
+
+int pa__init(pa_module*m) {
+ struct userdata *u = NULL;
+ pa_sample_spec ss;
+ pa_modargs *ma = NULL;
+ const char *server;
+ pa_sink_new_data data;
+
+ pa_assert(m);
+
+ if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
+ pa_log("failed to parse module arguments");
+ goto fail;
+ }
+
+ ss = m->core->default_sample_spec;
+ if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
+ pa_log("invalid sample format specification");
+ goto fail;
+ }
+
+ if ((/*ss.format != PA_SAMPLE_U8 &&*/ ss.format != PA_SAMPLE_S16NE) ||
+ (ss.channels > 2)) {
+ pa_log("sample type support is limited to mono/stereo and U8 or S16NE sample data");
+ goto fail;
+ }
+
+ u = pa_xnew0(struct userdata, 1);
+ u->core = m->core;
+ u->module = m;
+ m->userdata = u;
+ u->fd = -1;
+ u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC*2, TRUE, 10);
+ pa_memchunk_reset(&u->raw_memchunk);
+ pa_memchunk_reset(&u->encoded_memchunk);
+ u->offset = 0;
+ u->encoding_overhead = 0;
+ u->next_encoding_overhead = 0;
+ u->encoding_ratio = 1.0;
+
+ u->volume = roundf(0.7 * PA_VOLUME_NORM);
+ u->muted = FALSE;
+
+ u->rtpoll = pa_rtpoll_new();
+ pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
+ u->rtpoll_item = NULL;
+
+ /*u->format =
+ (ss.format == PA_SAMPLE_U8 ? ESD_BITS8 : ESD_BITS16) |
+ (ss.channels == 2 ? ESD_STEREO : ESD_MONO);*/
+ u->rate = ss.rate;
+ u->block_size = pa_usec_to_bytes(PA_USEC_PER_SEC/20, &ss);
+
+ u->read_data = u->write_data = NULL;
+ u->read_index = u->write_index = u->read_length = u->write_length = 0;
+
+ /*u->state = STATE_AUTH;*/
+ u->latency = 0;
+
+ if (!(server = pa_modargs_get_value(ma, "server", NULL))) {
+ pa_log("No server argument given.");
+ goto fail;
+ }
+
+ pa_sink_new_data_init(&data);
+ data.driver = __FILE__;
+ data.module = m;
+ pa_sink_new_data_set_name(&data, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME));
+ pa_sink_new_data_set_sample_spec(&data, &ss);
+ pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server);
+ pa_proplist_setf(data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Airtunes sink '%s'", server);
+
+ u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY|PA_SINK_NETWORK);
+ pa_sink_new_data_done(&data);
+
+ if (!u->sink) {
+ pa_log("Failed to create sink.");
+ goto fail;
+ }
+
+ u->sink->parent.process_msg = sink_process_msg;
+ u->sink->userdata = u;
+ u->sink->get_volume = sink_get_volume_cb;
+ u->sink->set_volume = sink_set_volume_cb;
+ u->sink->get_mute = sink_get_mute_cb;
+ u->sink->set_mute = sink_set_mute_cb;
+ u->sink->flags = PA_SINK_LATENCY|PA_SINK_NETWORK|PA_SINK_HW_VOLUME_CTRL;
+
+ pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
+ pa_sink_set_rtpoll(u->sink, u->rtpoll);
+
+ if (!(u->raop = pa_raop_client_new(u->core, server))) {
+ pa_log("Failed to connect to server.");
+ goto fail;
+ }
+
+ pa_raop_client_set_callback(u->raop, on_connection, u);
+ pa_raop_client_set_closed_callback(u->raop, on_close, u);
+
+ if (!(u->thread = pa_thread_new(thread_func, u))) {
+ pa_log("Failed to create 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);
+ }
+
+ pa_thread_mq_done(&u->thread_mq);
+
+ if (u->sink)
+ pa_sink_unref(u->sink);
+
+ if (u->rtpoll_item)
+ pa_rtpoll_item_free(u->rtpoll_item);
+
+ if (u->rtpoll)
+ pa_rtpoll_free(u->rtpoll);
+
+ if (u->raw_memchunk.memblock)
+ pa_memblock_unref(u->raw_memchunk.memblock);
+
+ if (u->encoded_memchunk.memblock)
+ pa_memblock_unref(u->encoded_memchunk.memblock);
+
+ if (u->raop)
+ pa_raop_client_free(u->raop);
+
+ pa_xfree(u->read_data);
+ pa_xfree(u->write_data);
+
+ if (u->smoother)
+ pa_smoother_free(u->smoother);
+
+ if (u->fd >= 0)
+ pa_close(u->fd);
+
+ pa_xfree(u);
+}
diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c
index 5b2be118..976a8ce5 100644
--- a/src/modules/module-remap-sink.c
+++ b/src/modules/module-remap-sink.c
@@ -274,6 +274,16 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
}
}
+/* Called from main context */
+static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
+ struct userdata *u;
+
+ pa_sink_input_assert_ref(i);
+ pa_assert_se(u = i->userdata);
+
+ return u->sink != dest;
+}
+
int pa__init(pa_module*m) {
struct userdata *u;
pa_sample_spec ss;
@@ -386,6 +396,7 @@ int pa__init(pa_module*m) {
u->sink_input->detach = sink_input_detach_cb;
u->sink_input->kill = sink_input_kill_cb;
u->sink_input->state_change = sink_input_state_change_cb;
+ u->sink_input->may_move_to = sink_input_may_move_to_cb;
u->sink_input->userdata = u;
pa_sink_put(u->sink);
diff --git a/src/modules/module-sine.c b/src/modules/module-sine.c
index a6324526..21565cc4 100644
--- a/src/modules/module-sine.c
+++ b/src/modules/module-sine.c
@@ -116,13 +116,13 @@ static void sink_input_state_change_cb(pa_sink_input *i, pa_sink_input_state_t s
pa_sink_input_request_rewind(i, 0, FALSE, TRUE);
}
-static void calc_sine(float *f, size_t l, float freq) {
+static void calc_sine(float *f, size_t l, double freq) {
size_t i;
l /= sizeof(float);
for (i = 0; i < l; i++)
- f[i] = (float) sin((double) i/l*M_PI*2*freq)/2;
+ f[i] = (float) sin((double) i/(double)l*M_PI*2*freq)/2;
}
int pa__init(pa_module*m) {
@@ -163,7 +163,7 @@ int pa__init(pa_module*m) {
u->memblock = pa_memblock_new(m->core->mempool, pa_bytes_per_second(&ss));
p = pa_memblock_acquire(u->memblock);
- calc_sine(p, pa_memblock_get_length(u->memblock), frequency);
+ calc_sine(p, pa_memblock_get_length(u->memblock), (double) frequency);
pa_memblock_release(u->memblock);
pa_sink_input_new_data_init(&data);
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index ec4e7c79..55897004 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -134,7 +134,7 @@ static char *get_name(pa_proplist *p, const char *prefix) {
else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
return pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
- return NULL;
+ return pa_sprintf_malloc("%s-fallback:%s", prefix, r);
}
static struct entry* read_entry(struct userdata *u, char *name) {
@@ -145,7 +145,7 @@ static struct entry* read_entry(struct userdata *u, char *name) {
pa_assert(name);
key.dptr = name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data = gdbm_fetch(u->gdbm_file, key);
@@ -277,7 +277,7 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
}
key.dptr = name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
@@ -306,8 +306,11 @@ static pa_hook_result_t sink_input_new_hook_callback(pa_core *c, pa_sink_input_n
if (u->restore_device &&
(s = pa_namereg_get(c, e->device, PA_NAMEREG_SINK, TRUE))) {
- pa_log_info("Restoring device for stream %s.", name);
- new_data->sink = s;
+ if (!new_data->sink) {
+ pa_log_info("Restoring device for stream %s.", name);
+ new_data->sink = s;
+ } else
+ pa_log_info("Not restore device for stream %s, because already set.", name);
}
pa_xfree(e);
@@ -330,13 +333,20 @@ static pa_hook_result_t sink_input_fixate_hook_callback(pa_core *c, pa_sink_inpu
if ((e = read_entry(u, name))) {
if (u->restore_volume) {
- pa_log_info("Restoring volume for sink input %s.", name);
- pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+
+ if (!new_data->volume_is_set) {
+ pa_log_info("Restoring volume for sink input %s.", name);
+ pa_sink_input_new_data_set_volume(new_data, pa_cvolume_remap(&e->volume, &e->channel_map, &new_data->channel_map));
+ } else
+ pa_log_debug("Not restoring volume for sink input %s, because already set.", name);
}
if (u->restore_muted) {
- pa_log_info("Restoring mute state for sink input %s.", name);
- pa_sink_input_new_data_set_muted(new_data, e->muted);
+ if (!new_data->muted_is_set) {
+ pa_log_info("Restoring mute state for sink input %s.", name);
+ pa_sink_input_new_data_set_muted(new_data, e->muted);
+ } else
+ pa_log_debug("Not restoring mute state for sink input %s, because already set.", name);
}
pa_xfree(e);
@@ -360,10 +370,14 @@ static pa_hook_result_t source_output_new_hook_callback(pa_core *c, pa_source_ou
pa_source *s;
if (u->restore_device &&
+ !new_data->direct_on_input &&
(s = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE, TRUE))) {
- pa_log_info("Restoring device for stream %s.", name);
- new_data->source = s;
+ if (!new_data->source) {
+ pa_log_info("Restoring device for stream %s.", name);
+ new_data->source = s;
+ } else
+ pa_log_info("Not restoring device for stream %s, because already set", name);
}
pa_xfree(e);
@@ -408,7 +422,7 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
char *n;
pa_sink *s;
- if (!(n = get_name(si->proplist, "sink_input")))
+ if (!(n = get_name(si->proplist, "sink-input")))
continue;
if (strcmp(name, n)) {
@@ -417,8 +431,9 @@ static void apply_entry(struct userdata *u, const char *name, struct entry *e) {
}
if (u->restore_volume) {
+ pa_cvolume v = e->volume;
pa_log_info("Restoring volume for sink input %s.", name);
- pa_sink_input_set_volume(si, pa_cvolume_remap(&e->volume, &e->channel_map, &si->channel_map));
+ pa_sink_input_set_volume(si, pa_cvolume_remap(&v, &e->channel_map, &si->channel_map));
}
if (u->restore_muted) {
@@ -490,7 +505,7 @@ static void dump_database(struct userdata *u) {
static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connection *c, uint32_t tag, pa_tagstruct *t) {
struct userdata *u;
uint32_t command;
- pa_tagstruct *reply;
+ pa_tagstruct *reply = NULL;
pa_assert(p);
pa_assert(m);
@@ -529,7 +544,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
next_key = gdbm_nextkey(u->gdbm_file, key);
- name = pa_xstrndup(key.dptr, key.dsize);
+ name = pa_xstrndup(key.dptr, (size_t) key.dsize);
pa_xfree(key.dptr);
if ((e = read_entry(u, name))) {
@@ -552,7 +567,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
case SUBCOMMAND_WRITE: {
uint32_t mode;
- pa_bool_t apply_immediately;
+ pa_bool_t apply_immediately = FALSE;
if (pa_tagstruct_getu32(t, &mode) < 0 ||
pa_tagstruct_get_boolean(t, &apply_immediately) < 0)
@@ -571,6 +586,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
pa_bool_t muted;
struct entry entry;
datum key, data;
+ int k;
memset(&entry, 0, sizeof(entry));
@@ -588,12 +604,12 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
pa_strlcpy(entry.device, device, sizeof(entry.device));
key.dptr = (void*) name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
data.dptr = (void*) &entry;
data.dsize = sizeof(entry);
- if (gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT) == 1)
+ if ((k = gdbm_store(u->gdbm_file, key, data, mode == PA_UPDATE_REPLACE ? GDBM_REPLACE : GDBM_INSERT)) == 0)
if (apply_immediately)
apply_entry(u, name, &entry);
}
@@ -613,7 +629,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
goto fail;
key.dptr = (void*) name;
- key.dsize = strlen(name);
+ key.dsize = (int) strlen(name);
gdbm_delete(u->gdbm_file, key);
}
@@ -670,6 +686,7 @@ int pa__init(pa_module*m) {
pa_source_output *so;
uint32_t idx;
pa_bool_t restore_device = TRUE, restore_volume = TRUE, restore_muted = TRUE;
+ int gdbm_cache_size;
pa_assert(m);
@@ -730,6 +747,10 @@ int pa__init(pa_module*m) {
goto fail;
}
+ /* By default the cache of gdbm is rather large, let's reduce it a bit to save memory */
+ gdbm_cache_size = 10;
+ gdbm_setopt(u->gdbm_file, GDBM_CACHESIZE, &gdbm_cache_size, sizeof(gdbm_cache_size));
+
pa_log_info("Sucessfully opened database file '%s'.", fname);
pa_xfree(fname);
diff --git a/src/modules/module-suspend-on-idle.c b/src/modules/module-suspend-on-idle.c
index bc7c023c..8ab84e08 100644
--- a/src/modules/module-suspend-on-idle.c
+++ b/src/modules/module-suspend-on-idle.c
@@ -83,12 +83,12 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval
d->userdata->core->mainloop->time_restart(d->time_event, NULL);
- if (d->sink && pa_sink_used_by(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) {
+ if (d->sink && pa_sink_check_suspend(d->sink) <= 0 && pa_sink_get_state(d->sink) != PA_SINK_SUSPENDED) {
pa_log_info("Sink %s idle for too long, suspending ...", d->sink->name);
pa_sink_suspend(d->sink, TRUE);
}
- if (d->source && pa_source_used_by(d->source) <= 0 && pa_source_get_state(d->source) != PA_SOURCE_SUSPENDED) {
+ if (d->source && pa_source_check_suspend(d->source) <= 0 && pa_source_get_state(d->source) != PA_SOURCE_SUSPENDED) {
pa_log_info("Source %s idle for too long, suspending ...", d->source->name);
pa_source_suspend(d->source, TRUE);
}
@@ -158,7 +158,7 @@ static pa_hook_result_t sink_input_unlink_hook_cb(pa_core *c, pa_sink_input *s,
pa_sink_input_assert_ref(s);
pa_assert(u);
- if (pa_sink_used_by(s->sink) <= 0) {
+ if (pa_sink_check_suspend(s->sink) <= 0) {
struct device_info *d;
if ((d = pa_hashmap_get(u->device_infos, s->sink)))
restart(d);
@@ -172,7 +172,7 @@ static pa_hook_result_t source_output_unlink_hook_cb(pa_core *c, pa_source_outpu
pa_source_output_assert_ref(s);
pa_assert(u);
- if (pa_source_used_by(s->source) <= 0) {
+ if (pa_source_check_suspend(s->source) <= 0) {
struct device_info *d;
if ((d = pa_hashmap_get(u->device_infos, s->source)))
restart(d);
@@ -191,7 +191,7 @@ static pa_hook_result_t sink_input_move_hook_cb(pa_core *c, pa_sink_input_move_h
if ((d = pa_hashmap_get(u->device_infos, data->destination)))
resume(d);
- if (pa_sink_used_by(data->sink_input->sink) <= 1)
+ if (pa_sink_check_suspend(data->sink_input->sink) <= 1)
if ((d = pa_hashmap_get(u->device_infos, data->sink_input->sink)))
restart(d);
@@ -208,7 +208,7 @@ static pa_hook_result_t source_output_move_hook_cb(pa_core *c, pa_source_output_
if ((d = pa_hashmap_get(u->device_infos, data->destination)))
resume(d);
- if (pa_source_used_by(data->source_output->source) <= 1)
+ if (pa_source_check_suspend(data->source_output->source) <= 1)
if ((d = pa_hashmap_get(u->device_infos, data->source_output->source)))
restart(d);
@@ -266,8 +266,8 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
d->time_event = c->mainloop->time_new(c->mainloop, NULL, timeout_cb, d);
pa_hashmap_put(u->device_infos, o, d);
- if ((d->sink && pa_sink_used_by(d->sink) <= 0) ||
- (d->source && pa_source_used_by(d->source) <= 0))
+ if ((d->sink && pa_sink_check_suspend(d->sink) <= 0) ||
+ (d->source && pa_source_check_suspend(d->source) <= 0))
restart(d);
return PA_HOOK_OK;
@@ -313,7 +313,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
pa_sink *s = PA_SINK(o);
pa_sink_state_t state = pa_sink_get_state(s);
- if (pa_sink_used_by(s) <= 0) {
+ if (pa_sink_check_suspend(s) <= 0) {
if (PA_SINK_IS_OPENED(state))
restart(d);
@@ -324,7 +324,7 @@ static pa_hook_result_t device_state_changed_hook_cb(pa_core *c, pa_object *o, s
pa_source *s = PA_SOURCE(o);
pa_source_state_t state = pa_source_get_state(s);
- if (pa_source_used_by(s) <= 0) {
+ if (pa_source_check_suspend(s) <= 0) {
if (PA_SOURCE_IS_OPENED(state))
restart(d);
@@ -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 79ce1dd2..a46d6e59 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 {
@@ -178,7 +178,7 @@ struct userdata {
#ifdef TUNNEL_SINK
char *sink_name;
pa_sink *sink;
- int32_t requested_bytes;
+ size_t requested_bytes;
#else
char *source_name;
pa_source *source;
@@ -389,7 +389,7 @@ static void send_data(struct userdata *u) {
u->requested_bytes -= memchunk.length;
- u->counter += memchunk.length;
+ u->counter += (int64_t) memchunk.length;
}
}
@@ -417,7 +417,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
case PA_SINK_MESSAGE_GET_LATENCY: {
pa_usec_t yl, yr, *usec = data;
- yl = pa_bytes_to_usec(u->counter, &u->sink->sample_spec);
+ yl = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec);
yr = pa_smoother_get(u->smoother, pa_rtclock_usec());
*usec = yl > yr ? yl - yr : 0;
@@ -444,10 +444,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
case SINK_MESSAGE_UPDATE_LATENCY: {
pa_usec_t y;
- y = pa_bytes_to_usec(u->counter, &u->sink->sample_spec);
+ y = pa_bytes_to_usec((uint64_t) u->counter, &u->sink->sample_spec);
if (y > (pa_usec_t) offset || offset < 0)
- y -= offset;
+ y -= (pa_usec_t) offset;
else
y = 0;
@@ -465,7 +465,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_pstream_send_memblock(u->pstream, u->channel, 0, PA_SEEK_RELATIVE, chunk);
- u->counter_delta += chunk->length;
+ u->counter_delta += (int64_t) chunk->length;
return 0;
}
@@ -508,7 +508,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
switch (code) {
- case PA_SINK_MESSAGE_SET_STATE: {
+ case PA_SOURCE_MESSAGE_SET_STATE: {
int r;
if ((r = pa_source_process_msg(o, code, data, offset, chunk)) >= 0)
@@ -520,7 +520,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
case PA_SOURCE_MESSAGE_GET_LATENCY: {
pa_usec_t yr, yl, *usec = data;
- yl = pa_bytes_to_usec(u->counter, &PA_SINK(o)->sample_spec);
+ yl = pa_bytes_to_usec((uint64_t) u->counter, &PA_SOURCE(o)->sample_spec);
yr = pa_smoother_get(u->smoother, pa_rtclock_usec());
*usec = yr > yl ? yr - yl : 0;
@@ -532,7 +532,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
if (PA_SOURCE_IS_OPENED(u->source->thread_info.state))
pa_source_post(u->source, chunk);
- u->counter += chunk->length;
+ u->counter += (int64_t) chunk->length;
return 0;
@@ -544,10 +544,10 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
case SOURCE_MESSAGE_UPDATE_LATENCY: {
pa_usec_t y;
- y = pa_bytes_to_usec(u->counter, &u->source->sample_spec);
+ y = pa_bytes_to_usec((uint64_t) u->counter, &u->source->sample_spec);
if (offset >= 0 || y > (pa_usec_t) -offset)
- y += offset;
+ y += (pa_usec_t) offset;
else
y = 0;
@@ -736,9 +736,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
/* Add the length of our server-side buffer */
if (write_index >= read_index)
- delay += (int64_t) pa_bytes_to_usec(write_index-read_index, ss);
+ delay += (int64_t) pa_bytes_to_usec((uint64_t) (write_index-read_index), ss);
else
- delay -= (int64_t) pa_bytes_to_usec(read_index-write_index, ss);
+ delay -= (int64_t) pa_bytes_to_usec((uint64_t) (read_index-write_index), ss);
/* Our measurements are already out of date, hence correct by the *
* transport latency */
@@ -750,9 +750,9 @@ static void stream_get_latency_callback(pa_pdispatch *pd, uint32_t command, uint
/* Now correct by what we have have read/written since we requested the update */
#ifdef TUNNEL_SINK
- delay += (int64_t) pa_bytes_to_usec(u->counter_delta, ss);
+ delay += (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss);
#else
- delay -= (int64_t) pa_bytes_to_usec(u->counter_delta, ss);
+ delay -= (int64_t) pa_bytes_to_usec((uint64_t) u->counter_delta, ss);
#endif
#ifdef TUNNEL_SINK
@@ -1425,11 +1425,11 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
u->maxlength = 4*1024*1024;
#ifdef TUNNEL_SINK
- u->tlength = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
- u->minreq = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
+ u->tlength = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
+ u->minreq = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
u->prebuf = u->tlength;
#else
- u->fragsize = pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
+ u->fragsize = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
#endif
#ifdef TUNNEL_SINK
@@ -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);
@@ -1548,7 +1555,7 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_POST, PA_UINT_TO_PTR(seek), offset, chunk);
- u->counter_delta += chunk->length;
+ u->counter_delta += (int64_t) chunk->length;
}
#endif
diff --git a/src/modules/module-volume-restore.c b/src/modules/module-volume-restore.c
index 0fb17a0d..aac0d046 100644
--- a/src/modules/module-volume-restore.c
+++ b/src/modules/module-volume-restore.c
@@ -103,7 +103,7 @@ static pa_cvolume* parse_volume(const char *s, pa_cvolume *v) {
if (k <= 0 || k > (long) PA_CHANNELS_MAX)
return NULL;
- v->channels = (unsigned) k;
+ v->channels = (uint8_t) k;
for (i = 0; i < v->channels; i++) {
p += strspn(p, WHITESPACE);
diff --git a/src/modules/module-x11-bell.c b/src/modules/module-x11-bell.c
index ae16b9ae..e93721c1 100644
--- a/src/modules/module-x11-bell.c
+++ b/src/modules/module-x11-bell.c
@@ -82,7 +82,7 @@ static int x11_event_cb(pa_x11_wrapper *w, XEvent *e, void *userdata) {
bne = (XkbBellNotifyEvent*) e;
- if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, TRUE, (bne->percent*PA_VOLUME_NORM)/100, NULL, NULL) < 0) {
+ if (pa_scache_play_item_by_name(u->core, u->scache_item, u->sink_name, TRUE, ((pa_volume_t) bne->percent*PA_VOLUME_NORM)/100U, NULL, NULL) < 0) {
pa_log_info("Ringing bell failed, reverting to X11 device bell.");
XkbForceDeviceBell(pa_x11_wrapper_get_display(w), bne->device, bne->bell_class, bne->bell_id, bne->percent);
}
diff --git a/src/modules/module-x11-xsmp.c b/src/modules/module-x11-xsmp.c
index 12e100b7..57d182fd 100644
--- a/src/modules/module-x11-xsmp.c
+++ b/src/modules/module-x11-xsmp.c
@@ -181,7 +181,7 @@ int pa__init(pa_module*m) {
prop_program.name = (char*) SmProgram;
prop_program.type = (char*) SmARRAY8;
val_program.value = (char*) PACKAGE_NAME;
- val_program.length = strlen(val_program.value);
+ val_program.length = (int) strlen(val_program.value);
prop_program.num_vals = 1;
prop_program.vals = &val_program;
prop_list[0] = &prop_program;
@@ -190,7 +190,7 @@ int pa__init(pa_module*m) {
prop_user.type = (char*) SmARRAY8;
pa_get_user_name(t, sizeof(t));
val_user.value = t;
- val_user.length = strlen(val_user.value);
+ val_user.length = (int) strlen(val_user.value);
prop_user.num_vals = 1;
prop_user.vals = &val_user;
prop_list[1] = &prop_user;
diff --git a/src/modules/module-zeroconf-discover.c b/src/modules/module-zeroconf-discover.c
index a4fbf020..c8087abb 100644
--- a/src/modules/module-zeroconf-discover.c
+++ b/src/modules/module-zeroconf-discover.c
@@ -173,9 +173,9 @@ static void resolver_cb(
device = value;
value = NULL;
} else if (strcmp(key, "rate") == 0)
- ss.rate = atoi(value);
+ ss.rate = (uint32_t) atoi(value);
else if (strcmp(key, "channels") == 0)
- ss.channels = atoi(value);
+ ss.channels = (uint8_t) atoi(value);
else if (strcmp(key, "format") == 0)
ss.format = pa_parse_sample_format(value);
else if (strcmp(key, "channel_map") == 0) {
diff --git a/src/modules/oss-util.c b/src/modules/oss-util.c
index 2791e165..f766030d 100644
--- a/src/modules/oss-util.c
+++ b/src/modules/oss-util.c
@@ -204,10 +204,10 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) {
if (ss->channels != channels) {
pa_log_warn("device doesn't support %i channels, using %i channels.", ss->channels, channels);
- ss->channels = channels;
+ ss->channels = (uint8_t) channels;
}
- speed = ss->rate;
+ speed = (int) ss->rate;
if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) < 0) {
pa_log("SNDCTL_DSP_SPEED: %s", pa_cstrerror(errno));
return -1;
@@ -219,7 +219,7 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) {
/* If the sample rate deviates too much, we need to resample */
if (speed < ss->rate*.95 || speed > ss->rate*1.05)
- ss->rate = speed;
+ ss->rate = (uint32_t) speed;
}
return 0;
diff --git a/src/modules/raop/base64.c b/src/modules/raop/base64.c
new file mode 100644
index 00000000..8918def8
--- /dev/null
+++ b/src/modules/raop/base64.c
@@ -0,0 +1,126 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+
+ 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.
+***/
+
+/*
+ This file was originally inspired by a file developed by
+ Kungliga Tekniska H�gskolan
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <pulse/xmalloc.h>
+
+#include "base64.h"
+
+static const char base64_chars[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static int pos(char c)
+{
+ if (c >= 'A' && c <= 'Z') return c - 'A' + 0;
+ if (c >= 'a' && c <= 'z') return c - 'a' + 26;
+ if (c >= '0' && c <= '9') return c - '0' + 52;
+ if (c == '+') return 62;
+ if (c == '/') return 63;
+}
+
+int pa_base64_encode(const void *data, int size, char **str)
+{
+ char *s, *p;
+ int i;
+ int c;
+ const unsigned char *q;
+
+ p = s = pa_xnew(char, size * 4 / 3 + 4);
+ q = (const unsigned char *) data;
+ i = 0;
+ for (i = 0; i < size;) {
+ c = q[i++];
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ c *= 256;
+ if (i < size)
+ c += q[i];
+ i++;
+ p[0] = base64_chars[(c & 0x00fc0000) >> 18];
+ p[1] = base64_chars[(c & 0x0003f000) >> 12];
+ p[2] = base64_chars[(c & 0x00000fc0) >> 6];
+ p[3] = base64_chars[(c & 0x0000003f) >> 0];
+ if (i > size)
+ p[3] = '=';
+ if (i > size + 1)
+ p[2] = '=';
+ p += 4;
+ }
+ *p = 0;
+ *str = s;
+ return strlen(s);
+}
+
+#define DECODE_ERROR 0xffffffff
+
+static unsigned int token_decode(const char *token)
+{
+ int i;
+ unsigned int val = 0;
+ int marker = 0;
+ if (strlen(token) < 4)
+ return DECODE_ERROR;
+ for (i = 0; i < 4; i++) {
+ val *= 64;
+ if (token[i] == '=')
+ marker++;
+ else if (marker > 0)
+ return DECODE_ERROR;
+ else
+ val += pos(token[i]);
+ }
+ if (marker > 2)
+ return DECODE_ERROR;
+ return (marker << 24) | val;
+}
+
+int pa_base64_decode(const char *str, void *data)
+{
+ const char *p;
+ unsigned char *q;
+
+ q = data;
+ for (p = str; *p && (*p == '=' || strchr(base64_chars, *p)); p += 4) {
+ unsigned int val = token_decode(p);
+ unsigned int marker = (val >> 24) & 0xff;
+ if (val == DECODE_ERROR)
+ return -1;
+ *q++ = (val >> 16) & 0xff;
+ if (marker < 2)
+ *q++ = (val >> 8) & 0xff;
+ if (marker < 1)
+ *q++ = val & 0xff;
+ }
+ return q - (unsigned char *) data;
+}
diff --git a/src/modules/raop/base64.h b/src/modules/raop/base64.h
new file mode 100644
index 00000000..dac0e707
--- /dev/null
+++ b/src/modules/raop/base64.h
@@ -0,0 +1,34 @@
+#ifndef foobase64hfoo
+#define foobase64hfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+ Copyright Kungliga Tekniska Høgskolan
+
+ 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.
+***/
+
+/*
+ This file was originally inspired by a file developed by
+ Kungliga Tekniska Høgskolan
+*/
+
+int pa_base64_encode(const void *data, int size, char **str);
+int pa_base64_decode(const char *str, void *data);
+
+#endif
diff --git a/src/modules/raop/raop_client.c b/src/modules/raop/raop_client.c
new file mode 100644
index 00000000..4627545e
--- /dev/null
+++ b/src/modules/raop/raop_client.c
@@ -0,0 +1,561 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+
+ 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 <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+/* TODO: Replace OpenSSL with NSS */
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include <openssl/rsa.h>
+#include <openssl/engine.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/socket-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/strbuf.h>
+#include <pulsecore/random.h>
+#include <pulsecore/poll.h>
+
+#include "raop_client.h"
+#include "rtsp_client.h"
+#include "base64.h"
+
+#define AES_CHUNKSIZE 16
+
+#define JACK_STATUS_DISCONNECTED 0
+#define JACK_STATUS_CONNECTED 1
+
+#define JACK_TYPE_ANALOG 0
+#define JACK_TYPE_DIGITAL 1
+
+#define VOLUME_DEF -30
+#define VOLUME_MIN -144
+#define VOLUME_MAX 0
+
+
+struct pa_raop_client {
+ pa_core *core;
+ char *host;
+ char *sid;
+ pa_rtsp_client *rtsp;
+
+ uint8_t jack_type;
+ uint8_t jack_status;
+
+ /* Encryption Related bits */
+ AES_KEY aes;
+ uint8_t aes_iv[AES_CHUNKSIZE]; /* initialization vector for aes-cbc */
+ uint8_t aes_nv[AES_CHUNKSIZE]; /* next vector for aes-cbc */
+ uint8_t aes_key[AES_CHUNKSIZE]; /* key for aes-cbc */
+
+ pa_socket_client *sc;
+ int fd;
+
+ uint16_t seq;
+ uint32_t rtptime;
+
+ pa_raop_client_cb_t callback;
+ void* userdata;
+ pa_raop_client_closed_cb_t closed_callback;
+ void* closed_userdata;
+};
+
+/**
+ * Function to write bits into a buffer.
+ * @param buffer Handle to the buffer. It will be incremented if new data requires it.
+ * @param bit_pos A pointer to a position buffer to keep track the current write location (0 for MSB, 7 for LSB)
+ * @param size A pointer to the byte size currently written. This allows the calling function to do simple buffer overflow checks
+ * @param data The data to write
+ * @param data_bit_len The number of bits from data to write
+ */
+static inline void bit_writer(uint8_t **buffer, uint8_t *bit_pos, int *size, uint8_t data, uint8_t data_bit_len) {
+ int bits_left, bit_overflow;
+ uint8_t bit_data;
+
+ if (!data_bit_len)
+ return;
+
+ /* If bit pos is zero, we will definatly use at least one bit from the current byte so size increments. */
+ if (!*bit_pos)
+ *size += 1;
+
+ /* Calc the number of bits left in the current byte of buffer */
+ bits_left = 7 - *bit_pos + 1;
+ /* Calc the overflow of bits in relation to how much space we have left... */
+ bit_overflow = bits_left - data_bit_len;
+ if (bit_overflow >= 0) {
+ /* We can fit the new data in our current byte */
+ /* As we write from MSB->LSB we need to left shift by the overflow amount */
+ bit_data = data << bit_overflow;
+ if (*bit_pos)
+ **buffer |= bit_data;
+ else
+ **buffer = bit_data;
+ /* If our data fits exactly into the current byte, we need to increment our pointer */
+ if (0 == bit_overflow) {
+ /* Do not increment size as it will be incremeneted on next call as bit_pos is zero */
+ *buffer += 1;
+ *bit_pos = 0;
+ } else {
+ *bit_pos += data_bit_len;
+ }
+ } else {
+ /* bit_overflow is negative, there for we will need a new byte from our buffer */
+ /* Firstly fill up what's left in the current byte */
+ bit_data = data >> -bit_overflow;
+ **buffer |= bit_data;
+ /* Increment our buffer pointer and size counter*/
+ *buffer += 1;
+ *size += 1;
+ **buffer = data << (8 + bit_overflow);
+ *bit_pos = -bit_overflow;
+ }
+}
+
+static int rsa_encrypt(uint8_t *text, int len, uint8_t *res) {
+ const char n[] =
+ "59dE8qLieItsH1WgjrcFRKj6eUWqi+bGLOX1HL3U3GhC/j0Qg90u3sG/1CUtwC"
+ "5vOYvfDmFI6oSFXi5ELabWJmT2dKHzBJKa3k9ok+8t9ucRqMd6DZHJ2YCCLlDR"
+ "KSKv6kDqnw4UwPdpOMXziC/AMj3Z/lUVX1G7WSHCAWKf1zNS1eLvqr+boEjXuB"
+ "OitnZ/bDzPHrTOZz0Dew0uowxf/+sG+NCK3eQJVxqcaJ/vEHKIVd2M+5qL71yJ"
+ "Q+87X6oV3eaYvt3zWZYD6z5vYTcrtij2VZ9Zmni/UAaHqn9JdsBWLUEpVviYnh"
+ "imNVvYFZeCXg/IdTQ+x4IRdiXNv5hEew==";
+ const char e[] = "AQAB";
+ uint8_t modules[256];
+ uint8_t exponent[8];
+ int size;
+ RSA *rsa;
+
+ rsa = RSA_new();
+ size = pa_base64_decode(n, modules);
+ rsa->n = BN_bin2bn(modules, size, NULL);
+ size = pa_base64_decode(e, exponent);
+ rsa->e = BN_bin2bn(exponent, size, NULL);
+
+ size = RSA_public_encrypt(len, text, res, rsa, RSA_PKCS1_OAEP_PADDING);
+ RSA_free(rsa);
+ return size;
+}
+
+static int aes_encrypt(pa_raop_client* c, uint8_t *data, int size)
+{
+ uint8_t *buf;
+ int i=0, j;
+
+ pa_assert(c);
+
+ memcpy(c->aes_nv, c->aes_iv, AES_CHUNKSIZE);
+ while (i+AES_CHUNKSIZE <= size) {
+ buf = data + i;
+ for (j=0; j<AES_CHUNKSIZE; ++j)
+ buf[j] ^= c->aes_nv[j];
+
+ AES_encrypt(buf, buf, &c->aes);
+ memcpy(c->aes_nv, buf, AES_CHUNKSIZE);
+ i += AES_CHUNKSIZE;
+ }
+ return i;
+}
+
+static inline void rtrimchar(char *str, char rc)
+{
+ char *sp = str + strlen(str) - 1;
+ while (sp >= str && *sp == rc) {
+ *sp = '\0';
+ sp -= 1;
+ }
+}
+
+static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
+ pa_raop_client *c = userdata;
+
+ pa_assert(sc);
+ pa_assert(c);
+ pa_assert(c->sc == sc);
+ pa_assert(c->fd < 0);
+ pa_assert(c->callback);
+
+ pa_socket_client_unref(c->sc);
+ c->sc = NULL;
+
+ if (!io) {
+ pa_log("Connection failed: %s", pa_cstrerror(errno));
+ return;
+ }
+
+ c->fd = pa_iochannel_get_send_fd(io);
+
+ pa_iochannel_set_noclose(io, TRUE);
+ pa_iochannel_socket_set_sndbuf(io, 1024);
+ pa_iochannel_free(io);
+
+ pa_make_tcp_socket_low_delay(c->fd);
+
+ pa_log_debug("Connection established");
+ c->callback(c->fd, c->userdata);
+}
+
+static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* headers, void *userdata)
+{
+ pa_raop_client* c = userdata;
+ pa_assert(c);
+ pa_assert(rtsp);
+ pa_assert(rtsp == c->rtsp);
+
+ switch (state) {
+ case STATE_CONNECT: {
+ int i;
+ uint8_t rsakey[512];
+ char *key, *iv, *sac, *sdp;
+ uint16_t rand_data;
+ const char *ip;
+ char *url;
+
+ pa_log_debug("RAOP: CONNECTED");
+ ip = pa_rtsp_localip(c->rtsp);
+ /* First of all set the url properly */
+ url = pa_sprintf_malloc("rtsp://%s/%s", ip, c->sid);
+ pa_rtsp_set_url(c->rtsp, url);
+ pa_xfree(url);
+
+ /* Now encrypt our aes_public key to send to the device */
+ i = rsa_encrypt(c->aes_key, AES_CHUNKSIZE, rsakey);
+ pa_base64_encode(rsakey, i, &key);
+ rtrimchar(key, '=');
+ pa_base64_encode(c->aes_iv, AES_CHUNKSIZE, &iv);
+ rtrimchar(iv, '=');
+
+ pa_random(&rand_data, sizeof(rand_data));
+ pa_base64_encode(&rand_data, AES_CHUNKSIZE, &sac);
+ rtrimchar(sac, '=');
+ pa_rtsp_add_header(c->rtsp, "Apple-Challenge", sac);
+ sdp = pa_sprintf_malloc(
+ "v=0\r\n"
+ "o=iTunes %s 0 IN IP4 %s\r\n"
+ "s=iTunes\r\n"
+ "c=IN IP4 %s\r\n"
+ "t=0 0\r\n"
+ "m=audio 0 RTP/AVP 96\r\n"
+ "a=rtpmap:96 AppleLossless\r\n"
+ "a=fmtp:96 4096 0 16 40 10 14 2 255 0 0 44100\r\n"
+ "a=rsaaeskey:%s\r\n"
+ "a=aesiv:%s\r\n",
+ c->sid, ip, c->host, key, iv);
+ pa_rtsp_announce(c->rtsp, sdp);
+ pa_xfree(key);
+ pa_xfree(iv);
+ pa_xfree(sac);
+ pa_xfree(sdp);
+ break;
+ }
+
+ case STATE_ANNOUNCE:
+ pa_log_debug("RAOP: ANNOUNCED");
+ pa_rtsp_remove_header(c->rtsp, "Apple-Challenge");
+ pa_rtsp_setup(c->rtsp);
+ break;
+
+ case STATE_SETUP: {
+ char *aj = pa_xstrdup(pa_headerlist_gets(headers, "Audio-Jack-Status"));
+ pa_log_debug("RAOP: SETUP");
+ if (aj) {
+ char *token, *pc;
+ char delimiters[] = ";";
+ const char* token_state = NULL;
+ c->jack_type = JACK_TYPE_ANALOG;
+ c->jack_status = JACK_STATUS_DISCONNECTED;
+
+ while ((token = pa_split(aj, delimiters, &token_state))) {
+ if ((pc = strstr(token, "="))) {
+ *pc = 0;
+ if (!strcmp(token, "type") && !strcmp(pc+1, "digital")) {
+ c->jack_type = JACK_TYPE_DIGITAL;
+ }
+ } else {
+ if (!strcmp(token,"connected"))
+ c->jack_status = JACK_STATUS_CONNECTED;
+ }
+ pa_xfree(token);
+ }
+ pa_xfree(aj);
+ } else {
+ pa_log_warn("Audio Jack Status missing");
+ }
+ pa_rtsp_record(c->rtsp, &c->seq, &c->rtptime);
+ break;
+ }
+
+ case STATE_RECORD: {
+ uint32_t port = pa_rtsp_serverport(c->rtsp);
+ pa_log_debug("RAOP: RECORDED");
+
+ if (!(c->sc = pa_socket_client_new_string(c->core->mainloop, c->host, port))) {
+ pa_log("failed to connect to server '%s:%d'", c->host, port);
+ return;
+ }
+ pa_socket_client_set_callback(c->sc, on_connection, c);
+ break;
+ }
+
+ case STATE_FLUSH:
+ pa_log_debug("RAOP: FLUSHED");
+ break;
+
+ case STATE_TEARDOWN:
+ case STATE_SET_PARAMETER:
+ pa_log_debug("RAOP: SET_PARAMETER");
+ break;
+ case STATE_DISCONNECTED:
+ pa_assert(c->closed_callback);
+ pa_assert(c->rtsp);
+
+ pa_log_debug("RTSP control channel closed");
+ pa_rtsp_client_free(c->rtsp);
+ c->rtsp = NULL;
+ if (c->fd > 0) {
+ /* We do not close the fd, we leave it to the closed callback to do that */
+ c->fd = -1;
+ }
+ if (c->sc) {
+ pa_socket_client_unref(c->sc);
+ c->sc = NULL;
+ }
+ pa_xfree(c->sid);
+ c->sid = NULL;
+ c->closed_callback(c->closed_userdata);
+ break;
+ }
+}
+
+pa_raop_client* pa_raop_client_new(pa_core *core, const char* host)
+{
+ pa_raop_client* c = pa_xnew0(pa_raop_client, 1);
+
+ pa_assert(core);
+ pa_assert(host);
+
+ c->core = core;
+ c->fd = -1;
+ c->host = pa_xstrdup(host);
+
+ if (pa_raop_connect(c)) {
+ pa_raop_client_free(c);
+ return NULL;
+ }
+ return c;
+}
+
+
+void pa_raop_client_free(pa_raop_client* c)
+{
+ pa_assert(c);
+
+ if (c->rtsp)
+ pa_rtsp_client_free(c->rtsp);
+ pa_xfree(c->host);
+ pa_xfree(c);
+}
+
+
+int pa_raop_connect(pa_raop_client* c)
+{
+ char *sci;
+ struct {
+ uint32_t a;
+ uint32_t b;
+ uint32_t c;
+ } rand_data;
+
+ pa_assert(c);
+
+ if (c->rtsp) {
+ pa_log_debug("Connection already in progress");
+ return 0;
+ }
+
+ c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, 5000, "iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)");
+
+ /* Initialise the AES encryption system */
+ pa_random(c->aes_iv, sizeof(c->aes_iv));
+ pa_random(c->aes_key, sizeof(c->aes_key));
+ memcpy(c->aes_nv, c->aes_iv, sizeof(c->aes_nv));
+ AES_set_encrypt_key(c->aes_key, 128, &c->aes);
+
+ /* Generate random instance id */
+ pa_random(&rand_data, sizeof(rand_data));
+ c->sid = pa_sprintf_malloc("%u", rand_data.a);
+ sci = pa_sprintf_malloc("%08x%08x",rand_data.b, rand_data.c);
+ pa_rtsp_add_header(c->rtsp, "Client-Instance", sci);
+ pa_xfree(sci);
+ pa_rtsp_set_callback(c->rtsp, rtsp_cb, c);
+ return pa_rtsp_connect(c->rtsp);
+}
+
+
+int pa_raop_flush(pa_raop_client* c)
+{
+ pa_assert(c);
+
+ pa_rtsp_flush(c->rtsp, c->seq, c->rtptime);
+ return 0;
+}
+
+
+int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume)
+{
+ int rv;
+ double db;
+ char *param;
+
+ pa_assert(c);
+
+ db = pa_sw_volume_to_dB(volume);
+ if (db < VOLUME_MIN)
+ db = VOLUME_MIN;
+ else if (db > VOLUME_MAX)
+ db = VOLUME_MAX;
+
+ param = pa_sprintf_malloc("volume: %0.6f\r\n", db);
+
+ /* We just hit and hope, cannot wait for the callback */
+ rv = pa_rtsp_setparameter(c->rtsp, param);
+ pa_xfree(param);
+ return rv;
+}
+
+
+int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded)
+{
+ uint16_t len;
+ size_t bufmax;
+ uint8_t *bp, bpos;
+ uint8_t *ibp, *maxibp;
+ int size;
+ uint8_t *b, *p;
+ uint32_t bsize;
+ size_t length;
+ static uint8_t header[] = {
+ 0x24, 0x00, 0x00, 0x00,
+ 0xF0, 0xFF, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ };
+ int header_size = sizeof(header);
+
+ pa_assert(c);
+ pa_assert(c->fd > 0);
+ pa_assert(raw);
+ pa_assert(raw->memblock);
+ pa_assert(raw->length > 0);
+ pa_assert(encoded);
+
+ /* We have to send 4 byte chunks */
+ bsize = (int)(raw->length / 4);
+ length = bsize * 4;
+
+ /* Leave 16 bytes extra to allow for the ALAC header which is about 55 bits */
+ bufmax = length + header_size + 16;
+ pa_memchunk_reset(encoded);
+ encoded->memblock = pa_memblock_new(c->core->mempool, bufmax);
+ b = pa_memblock_acquire(encoded->memblock);
+ memcpy(b, header, header_size);
+
+ /* Now write the actual samples */
+ bp = b + header_size;
+ size = bpos = 0;
+ bit_writer(&bp,&bpos,&size,1,3); /* channel=1, stereo */
+ bit_writer(&bp,&bpos,&size,0,4); /* unknown */
+ bit_writer(&bp,&bpos,&size,0,8); /* unknown */
+ bit_writer(&bp,&bpos,&size,0,4); /* unknown */
+ bit_writer(&bp,&bpos,&size,1,1); /* hassize */
+ bit_writer(&bp,&bpos,&size,0,2); /* unused */
+ bit_writer(&bp,&bpos,&size,1,1); /* is-not-compressed */
+
+ /* size of data, integer, big endian */
+ bit_writer(&bp,&bpos,&size,(bsize>>24)&0xff,8);
+ bit_writer(&bp,&bpos,&size,(bsize>>16)&0xff,8);
+ bit_writer(&bp,&bpos,&size,(bsize>>8)&0xff,8);
+ bit_writer(&bp,&bpos,&size,(bsize)&0xff,8);
+
+ ibp = p = pa_memblock_acquire(raw->memblock);
+ maxibp = p + raw->length - 4;
+ while (ibp <= maxibp) {
+ /* Byte swap stereo data */
+ bit_writer(&bp,&bpos,&size,*(ibp+1),8);
+ bit_writer(&bp,&bpos,&size,*(ibp+0),8);
+ bit_writer(&bp,&bpos,&size,*(ibp+3),8);
+ bit_writer(&bp,&bpos,&size,*(ibp+2),8);
+ ibp += 4;
+ raw->index += 4;
+ raw->length -= 4;
+ }
+ pa_memblock_release(raw->memblock);
+ encoded->length = header_size + size;
+
+ /* store the lenght (endian swapped: make this better) */
+ len = size + header_size - 4;
+ *(b + 2) = len >> 8;
+ *(b + 3) = len & 0xff;
+
+ /* encrypt our data */
+ aes_encrypt(c, (b + header_size), size);
+
+ /* We're done with the chunk */
+ pa_memblock_release(encoded->memblock);
+
+ return 0;
+}
+
+
+void pa_raop_client_set_callback(pa_raop_client* c, pa_raop_client_cb_t callback, void *userdata)
+{
+ pa_assert(c);
+
+ c->callback = callback;
+ c->userdata = userdata;
+}
+
+void pa_raop_client_set_closed_callback(pa_raop_client* c, pa_raop_client_closed_cb_t callback, void *userdata)
+{
+ pa_assert(c);
+
+ c->closed_callback = callback;
+ c->closed_userdata = userdata;
+}
diff --git a/src/modules/raop/raop_client.h b/src/modules/raop/raop_client.h
new file mode 100644
index 00000000..ec3136a7
--- /dev/null
+++ b/src/modules/raop/raop_client.h
@@ -0,0 +1,46 @@
+#ifndef fooraopclientfoo
+#define fooraopclientfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#include <pulse/mainloop-api.h>
+#include <pulsecore/iochannel.h>
+#include <pulsecore/core.h>
+
+typedef struct pa_raop_client pa_raop_client;
+
+pa_raop_client* pa_raop_client_new(pa_core *core, const char* host);
+void pa_raop_client_free(pa_raop_client* c);
+
+int pa_raop_connect(pa_raop_client* c);
+int pa_raop_flush(pa_raop_client* c);
+
+int pa_raop_client_set_volume(pa_raop_client* c, pa_volume_t volume);
+int pa_raop_client_encode_sample(pa_raop_client* c, pa_memchunk* raw, pa_memchunk* encoded);
+
+typedef void (*pa_raop_client_cb_t)(int fd, void *userdata);
+void pa_raop_client_set_callback(pa_raop_client* c, pa_raop_client_cb_t callback, void *userdata);
+
+typedef void (*pa_raop_client_closed_cb_t)(void *userdata);
+void pa_raop_client_set_closed_callback(pa_raop_client* c, pa_raop_client_closed_cb_t callback, void *userdata);
+
+#endif
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/headerlist.c b/src/modules/rtp/headerlist.c
new file mode 100644
index 00000000..0fef835b
--- /dev/null
+++ b/src/modules/rtp/headerlist.c
@@ -0,0 +1,186 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+ Copyright 2007 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.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/hashmap.h>
+#include <pulsecore/strbuf.h>
+#include <pulsecore/core-util.h>
+
+#include "headerlist.h"
+
+struct header {
+ char *key;
+ void *value;
+ size_t nbytes;
+};
+
+#define MAKE_HASHMAP(p) ((pa_hashmap*) (p))
+#define MAKE_HEADERLIST(p) ((pa_headerlist*) (p))
+
+static void header_free(struct header *hdr) {
+ pa_assert(hdr);
+
+ pa_xfree(hdr->key);
+ pa_xfree(hdr->value);
+ pa_xfree(hdr);
+}
+
+pa_headerlist* pa_headerlist_new(void) {
+ return MAKE_HEADERLIST(pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func));
+}
+
+void pa_headerlist_free(pa_headerlist* p) {
+ struct header *hdr;
+
+ while ((hdr = pa_hashmap_steal_first(MAKE_HASHMAP(p))))
+ header_free(hdr);
+
+ pa_hashmap_free(MAKE_HASHMAP(p), NULL, NULL);
+}
+
+int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value) {
+ struct header *hdr;
+ pa_bool_t add = FALSE;
+
+ pa_assert(p);
+ pa_assert(key);
+
+ if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
+ hdr = pa_xnew(struct header, 1);
+ hdr->key = pa_xstrdup(key);
+ add = TRUE;
+ } else
+ pa_xfree(hdr->value);
+
+ hdr->value = pa_xstrdup(value);
+ hdr->nbytes = strlen(value)+1;
+
+ if (add)
+ pa_hashmap_put(MAKE_HASHMAP(p), hdr->key, hdr);
+
+ return 0;
+}
+
+int pa_headerlist_putsappend(pa_headerlist *p, const char *key, const char *value) {
+ struct header *hdr;
+ pa_bool_t add = FALSE;
+
+ pa_assert(p);
+ pa_assert(key);
+
+ if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key))) {
+ hdr = pa_xnew(struct header, 1);
+ hdr->key = pa_xstrdup(key);
+ hdr->value = pa_xstrdup(value);
+ add = TRUE;
+ } else {
+ void *newval = pa_sprintf_malloc("%s%s", (char*)hdr->value, value);
+ pa_xfree(hdr->value);
+ hdr->value = newval;
+ }
+ hdr->nbytes = strlen(hdr->value)+1;
+
+ if (add)
+ pa_hashmap_put(MAKE_HASHMAP(p), hdr->key, hdr);
+
+ return 0;
+}
+
+const char *pa_headerlist_gets(pa_headerlist *p, const char *key) {
+ struct header *hdr;
+
+ pa_assert(p);
+ pa_assert(key);
+
+ if (!(hdr = pa_hashmap_get(MAKE_HASHMAP(p), key)))
+ return NULL;
+
+ if (hdr->nbytes <= 0)
+ return NULL;
+
+ if (((char*) hdr->value)[hdr->nbytes-1] != 0)
+ return NULL;
+
+ if (strlen((char*) hdr->value) != hdr->nbytes-1)
+ return NULL;
+
+ return (char*) hdr->value;
+}
+
+int pa_headerlist_remove(pa_headerlist *p, const char *key) {
+ struct header *hdr;
+
+ pa_assert(p);
+ pa_assert(key);
+
+ if (!(hdr = pa_hashmap_remove(MAKE_HASHMAP(p), key)))
+ return -1;
+
+ header_free(hdr);
+ return 0;
+}
+
+const char *pa_headerlist_iterate(pa_headerlist *p, void **state) {
+ struct header *hdr;
+
+ if (!(hdr = pa_hashmap_iterate(MAKE_HASHMAP(p), state, NULL)))
+ return NULL;
+
+ return hdr->key;
+}
+
+char *pa_headerlist_to_string(pa_headerlist *p) {
+ const char *key;
+ void *state = NULL;
+ pa_strbuf *buf;
+
+ pa_assert(p);
+
+ buf = pa_strbuf_new();
+
+ while ((key = pa_headerlist_iterate(p, &state))) {
+
+ const char *v;
+
+ if ((v = pa_headerlist_gets(p, key)))
+ pa_strbuf_printf(buf, "%s: %s\r\n", key, v);
+ }
+
+ return pa_strbuf_tostring_free(buf);
+}
+
+int pa_headerlist_contains(pa_headerlist *p, const char *key) {
+ pa_assert(p);
+ pa_assert(key);
+
+ if (!(pa_hashmap_get(MAKE_HASHMAP(p), key)))
+ return 0;
+
+ return 1;
+}
diff --git a/src/modules/rtp/headerlist.h b/src/modules/rtp/headerlist.h
new file mode 100644
index 00000000..4b9c6433
--- /dev/null
+++ b/src/modules/rtp/headerlist.h
@@ -0,0 +1,46 @@
+#ifndef foopulseheaderlisthfoo
+#define foopulseheaderlisthfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+ Copyright 2007 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 <pulsecore/macro.h>
+
+typedef struct pa_headerlist pa_headerlist;
+
+pa_headerlist* pa_headerlist_new(void);
+void pa_headerlist_free(pa_headerlist* p);
+
+int pa_headerlist_puts(pa_headerlist *p, const char *key, const char *value);
+int pa_headerlist_putsappend(pa_headerlist *p, const char *key, const char *value);
+
+const char *pa_headerlist_gets(pa_headerlist *p, const char *key);
+
+int pa_headerlist_remove(pa_headerlist *p, const char *key);
+
+const char *pa_headerlist_iterate(pa_headerlist *p, void **state);
+
+char *pa_headerlist_to_string(pa_headerlist *p);
+
+int pa_headerlist_contains(pa_headerlist *p, const char *key);
+
+#endif
diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c
index e04e4611..e35773cc 100644
--- a/src/modules/rtp/module-rtp-recv.c
+++ b/src/modules/rtp/module-rtp-recv.c
@@ -238,25 +238,25 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
else
delta = j;
- pa_memblockq_seek(s->memblockq, delta * s->rtp_context.frame_size, PA_SEEK_RELATIVE);
+ pa_memblockq_seek(s->memblockq, delta * (int64_t) s->rtp_context.frame_size, PA_SEEK_RELATIVE);
pa_rtclock_get(&now);
- pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec(pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec));
+ pa_smoother_put(s->smoother, pa_timeval_load(&now), pa_bytes_to_usec((uint64_t) pa_memblockq_get_write_index(s->memblockq), &s->sink_input->sample_spec));
if (pa_memblockq_push(s->memblockq, &chunk) < 0) {
pa_log_warn("Queue overrun");
- pa_memblockq_seek(s->memblockq, chunk.length, PA_SEEK_RELATIVE);
+ 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);
/* The next timestamp we expect */
- s->offset = s->rtp_context.timestamp + (chunk.length / s->rtp_context.frame_size);
+ s->offset = s->rtp_context.timestamp + (uint32_t) (chunk.length / s->rtp_context.frame_size);
- pa_atomic_store(&s->timestamp, now.tv_sec);
+ pa_atomic_store(&s->timestamp, (int) now.tv_sec);
if (s->last_rate_update + RATE_UPDATE_INTERVAL < pa_timeval_load(&now)) {
pa_usec_t wi, ri, render_delay, sink_delay = 0, latency, fix;
@@ -265,7 +265,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
pa_log("Updating sample rate");
wi = pa_smoother_get(s->smoother, pa_timeval_load(&now));
- ri = pa_bytes_to_usec(pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec);
+ ri = pa_bytes_to_usec((uint64_t) pa_memblockq_get_read_index(s->memblockq), &s->sink_input->sample_spec);
if (PA_MSGOBJECT(s->sink_input->sink)->process_msg(PA_MSGOBJECT(s->sink_input->sink), PA_SINK_MESSAGE_GET_LATENCY, &sink_delay, 0, NULL) < 0)
sink_delay = 0;
@@ -291,7 +291,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
fix = latency - s->intended_latency;
/* How many samples is this per second? */
- fix_samples = fix * s->sink_input->thread_info.sample_spec.rate / RATE_UPDATE_INTERVAL;
+ fix_samples = (unsigned) (fix * (pa_usec_t) s->sink_input->thread_info.sample_spec.rate / (pa_usec_t) RATE_UPDATE_INTERVAL);
/* Check if deviation is in bounds */
if (fix_samples > s->sink_input->sample_spec.rate*.20)
@@ -431,7 +431,7 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
s->smoother = pa_smoother_new(PA_USEC_PER_SEC*5, PA_USEC_PER_SEC*2, TRUE, 10);
pa_smoother_set_time_offset(s->smoother, pa_timeval_load(&now));
s->last_rate_update = pa_timeval_load(&now);
- pa_atomic_store(&s->timestamp, now.tv_sec);
+ pa_atomic_store(&s->timestamp, (int) now.tv_sec);
if ((fd = mcast_socket((const struct sockaddr*) &sdp_info->sa, sdp_info->salen)) < 0)
goto fail;
@@ -566,7 +566,7 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event
} else {
struct timeval now;
pa_rtclock_get(&now);
- pa_atomic_store(&s->timestamp, now.tv_sec);
+ pa_atomic_store(&s->timestamp, (int) now.tv_sec);
pa_sdp_info_destroy(&info);
}
diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c
index 5e542253..8d1e92fe 100644
--- a/src/modules/rtp/module-rtp-send.c
+++ b/src/modules/rtp/module-rtp-send.c
@@ -67,10 +67,12 @@ PA_MODULE_USAGE(
"destination=<destination IP address> "
"port=<port number> "
"mtu=<maximum transfer unit> "
- "loop=<loopback to local host?>"
+ "loop=<loopback to local host?> "
+ "ttl=<ttl value>"
);
#define DEFAULT_PORT 46000
+#define DEFAULT_TTL 1
#define SAP_PORT 9875
#define DEFAULT_DESTINATION "224.0.0.56"
#define MEMBLOCKQ_MAXLENGTH (1024*170)
@@ -86,6 +88,7 @@ static const char* const valid_modargs[] = {
"port",
"mtu" ,
"loop",
+ "ttl",
NULL
};
@@ -167,7 +170,9 @@ int pa__init(pa_module*m) {
pa_modargs *ma = NULL;
const char *dest;
uint32_t port = DEFAULT_PORT, mtu;
- int af, fd = -1, sap_fd = -1;
+ uint32_t ttl = DEFAULT_TTL;
+ sa_family_t af;
+ int fd = -1, sap_fd = -1;
pa_source *s;
pa_sample_spec ss;
pa_channel_map cm;
@@ -219,14 +224,14 @@ int pa__init(pa_module*m) {
payload = pa_rtp_payload_from_sample_spec(&ss);
- mtu = pa_frame_align(DEFAULT_MTU, &ss);
+ mtu = (uint32_t) pa_frame_align(DEFAULT_MTU, &ss);
if (pa_modargs_get_value_u32(ma, "mtu", &mtu) < 0 || mtu < 1 || mtu % pa_frame_size(&ss) != 0) {
pa_log("Invalid MTU.");
goto fail;
}
- port = DEFAULT_PORT + ((rand() % 512) << 1);
+ port = DEFAULT_PORT + ((uint32_t) (rand() % 512) << 1);
if (pa_modargs_get_value_u32(ma, "port", &port) < 0 || port < 1 || port > 0xFFFF) {
pa_log("port= expects a numerical argument between 1 and 65535.");
goto fail;
@@ -235,16 +240,21 @@ int pa__init(pa_module*m) {
if (port & 1)
pa_log_warn("Port number not even as suggested in RFC3550!");
+ if (pa_modargs_get_value_u32(ma, "ttl", &ttl) < 0 || ttl < 1 || ttl > 0xFF) {
+ pa_log("ttl= expects a numerical argument between 1 and 255.");
+ goto fail;
+ }
+
dest = pa_modargs_get_value(ma, "destination", DEFAULT_DESTINATION);
if (inet_pton(AF_INET6, dest, &sa6.sin6_addr) > 0) {
sa6.sin6_family = af = AF_INET6;
- sa6.sin6_port = htons(port);
+ sa6.sin6_port = htons((uint16_t) port);
sap_sa6 = sa6;
sap_sa6.sin6_port = htons(SAP_PORT);
} else if (inet_pton(AF_INET, dest, &sa4.sin_addr) > 0) {
sa4.sin_family = af = AF_INET;
- sa4.sin_port = htons(port);
+ sa4.sin_port = htons((uint16_t) port);
sap_sa4 = sa4;
sap_sa4.sin_port = htons(SAP_PORT);
} else {
@@ -257,7 +267,7 @@ int pa__init(pa_module*m) {
goto fail;
}
- if (connect(fd, af == AF_INET ? (struct sockaddr*) &sa4 : (struct sockaddr*) &sa6, af == AF_INET ? sizeof(sa4) : sizeof(sa6)) < 0) {
+ if (connect(fd, af == AF_INET ? (struct sockaddr*) &sa4 : (struct sockaddr*) &sa6, (socklen_t) (af == AF_INET ? sizeof(sa4) : sizeof(sa6))) < 0) {
pa_log("connect() failed: %s", pa_cstrerror(errno));
goto fail;
}
@@ -267,7 +277,7 @@ int pa__init(pa_module*m) {
goto fail;
}
- if (connect(sap_fd, af == AF_INET ? (struct sockaddr*) &sap_sa4 : (struct sockaddr*) &sap_sa6, af == AF_INET ? sizeof(sap_sa4) : sizeof(sap_sa6)) < 0) {
+ if (connect(sap_fd, af == AF_INET ? (struct sockaddr*) &sap_sa4 : (struct sockaddr*) &sap_sa6, (socklen_t) (af == AF_INET ? sizeof(sap_sa4) : sizeof(sap_sa6))) < 0) {
pa_log("connect() failed: %s", pa_cstrerror(errno));
goto fail;
}
@@ -279,6 +289,15 @@ int pa__init(pa_module*m) {
goto fail;
}
+ if (ttl != DEFAULT_TTL) {
+ int _ttl = (int) ttl;
+
+ if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &_ttl, sizeof(_ttl)) < 0) {
+ pa_log("IP_MULTICAST_TTL failed: %s", pa_cstrerror(errno));
+ goto fail;
+ }
+ }
+
/* If the socket queue is full, let's drop packets */
pa_make_fd_nonblock(fd);
pa_make_udp_socket_low_delay(fd);
@@ -290,13 +309,14 @@ int pa__init(pa_module*m) {
pa_proplist_sets(data.proplist, "rtp.destination", dest);
pa_proplist_setf(data.proplist, "rtp.mtu", "%lu", (unsigned long) mtu);
pa_proplist_setf(data.proplist, "rtp.port", "%lu", (unsigned long) port);
+ pa_proplist_setf(data.proplist, "rtp.ttl", "%lu", (unsigned long) ttl);
data.driver = __FILE__;
data.module = m;
data.source = s;
pa_source_output_new_data_set_sample_spec(&data, &ss);
pa_source_output_new_data_set_channel_map(&data, &cm);
- o = pa_source_output_new(m->core, &data, 0);
+ o = pa_source_output_new(m->core, &data, PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND);
pa_source_output_new_data_done(&data);
if (!o) {
@@ -335,14 +355,14 @@ int pa__init(pa_module*m) {
p = pa_sdp_build(af,
af == AF_INET ? (void*) &((struct sockaddr_in*) &sa_dst)->sin_addr : (void*) &((struct sockaddr_in6*) &sa_dst)->sin6_addr,
af == AF_INET ? (void*) &sa4.sin_addr : (void*) &sa6.sin6_addr,
- n, port, payload, &ss);
+ n, (uint16_t) port, payload, &ss);
pa_xfree(n);
pa_rtp_context_init_send(&u->rtp_context, fd, m->core->cookie, payload, pa_frame_size(&ss));
pa_sap_context_init_send(&u->sap_context, sap_fd, p);
- pa_log_info("RTP stream initialized with mtu %u on %s:%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, u->rtp_context.ssrc, payload, u->rtp_context.sequence);
+ pa_log_info("RTP stream initialized with mtu %u on %s:%u ttl=%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dest, port, ttl, u->rtp_context.ssrc, payload, u->rtp_context.sequence);
pa_log_info("SDP-Data:\n%s\nEOF", p);
pa_sap_send(&u->sap_context, 0);
diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp.c
index 5a33ebc2..88351010 100644
--- a/src/modules/rtp/rtp.c
+++ b/src/modules/rtp/rtp.c
@@ -50,7 +50,7 @@ pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssr
c->sequence = (uint16_t) (rand()*rand());
c->timestamp = 0;
c->ssrc = ssrc ? ssrc : (uint32_t) (rand()*rand());
- c->payload = payload & 127;
+ c->payload = (uint8_t) (payload & 127U);
c->frame_size = frame_size;
pa_memchunk_reset(&c->memchunk);
@@ -99,7 +99,8 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
if (r < 0 || n >= size || iov_idx >= MAX_IOVECS) {
uint32_t header[3];
struct msghdr m;
- int k, i;
+ ssize_t k;
+ int i;
if (n > 0) {
header[0] = htonl(((uint32_t) 2 << 30) | ((uint32_t) c->payload << 16) | ((uint32_t) c->sequence));
@@ -112,7 +113,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
m.msg_name = NULL;
m.msg_namelen = 0;
m.msg_iov = iov;
- m.msg_iovlen = iov_idx;
+ m.msg_iovlen = (size_t) iov_idx;
m.msg_control = NULL;
m.msg_controllen = 0;
m.msg_flags = 0;
@@ -128,7 +129,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
} else
k = 0;
- c->timestamp += n/c->frame_size;
+ c->timestamp += (unsigned) (n/c->frame_size);
if (k < 0) {
if (errno != EAGAIN && errno != EINTR) /* If the queue is full, just ignore it */
@@ -162,7 +163,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
struct msghdr m;
struct iovec iov;
uint32_t header;
- int cc;
+ unsigned cc;
ssize_t r;
pa_assert(c);
@@ -197,7 +198,7 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
chunk->index = c->memchunk.index;
iov.iov_base = (uint8_t*) pa_memblock_acquire(chunk->memblock) + chunk->index;
- iov.iov_len = size;
+ iov.iov_len = (size_t) size;
m.msg_name = NULL;
m.msg_namelen = 0;
@@ -246,16 +247,16 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool) {
}
cc = (header >> 24) & 0xF;
- c->payload = (header >> 16) & 127;
- c->sequence = header & 0xFFFF;
+ c->payload = (uint8_t) ((header >> 16) & 127U);
+ c->sequence = (uint16_t) (header & 0xFFFFU);
- if (12 + cc*4 > size) {
+ if (12 + cc*4 > (unsigned) size) {
pa_log_warn("RTP packet too short. (CSRC)");
goto fail;
}
chunk->index += 12 + cc*4;
- chunk->length = size - 12 + cc*4;
+ chunk->length = (size_t) size - 12 + cc*4;
if (chunk->length % c->frame_size != 0) {
pa_log_warn("Bad RTP packet size.");
diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
new file mode 100644
index 00000000..9eb3d964
--- /dev/null
+++ b/src/modules/rtp/rtsp_client.c
@@ -0,0 +1,542 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+
+ 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 <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-error.h>
+#include <pulsecore/core-util.h>
+#include <pulsecore/socket-util.h>
+#include <pulsecore/log.h>
+#include <pulsecore/macro.h>
+#include <pulsecore/strbuf.h>
+#include <pulsecore/poll.h>
+#include <pulsecore/ioline.h>
+
+#include "rtsp_client.h"
+
+struct pa_rtsp_client {
+ pa_mainloop_api *mainloop;
+ char *hostname;
+ uint16_t port;
+
+ pa_socket_client *sc;
+ pa_iochannel *io;
+ pa_ioline *ioline;
+
+ pa_rtsp_cb_t callback;
+
+ void *userdata;
+ const char *useragent;
+
+ pa_rtsp_state state;
+ uint8_t waiting;
+
+ pa_headerlist* headers;
+ char *last_header;
+ pa_strbuf *header_buffer;
+ pa_headerlist* response_headers;
+
+ char *localip;
+ char *url;
+ uint16_t rtp_port;
+ uint32_t cseq;
+ char *session;
+ char *transport;
+};
+
+pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char* hostname, uint16_t port, const char* useragent) {
+ pa_rtsp_client *c;
+
+ pa_assert(mainloop);
+ pa_assert(hostname);
+ pa_assert(port > 0);
+
+ c = pa_xnew0(pa_rtsp_client, 1);
+ c->mainloop = mainloop;
+ c->hostname = pa_xstrdup(hostname);
+ c->port = port;
+ c->headers = pa_headerlist_new();
+
+ if (useragent)
+ c->useragent = useragent;
+ else
+ c->useragent = "PulseAudio RTSP Client";
+
+ return c;
+}
+
+
+void pa_rtsp_client_free(pa_rtsp_client* c) {
+ if (c) {
+ if (c->sc)
+ pa_socket_client_unref(c->sc);
+ if (c->ioline)
+ pa_ioline_close(c->ioline);
+ else if (c->io)
+ pa_iochannel_free(c->io);
+
+ pa_xfree(c->hostname);
+ pa_xfree(c->url);
+ pa_xfree(c->localip);
+ pa_xfree(c->session);
+ pa_xfree(c->transport);
+ pa_xfree(c->last_header);
+ if (c->header_buffer)
+ pa_strbuf_free(c->header_buffer);
+ if (c->response_headers)
+ pa_headerlist_free(c->response_headers);
+ pa_headerlist_free(c->headers);
+ }
+ pa_xfree(c);
+}
+
+
+static void headers_read(pa_rtsp_client *c) {
+ char* token;
+ char delimiters[] = ";";
+
+ pa_assert(c);
+ pa_assert(c->response_headers);
+ pa_assert(c->callback);
+
+ /* Deal with a SETUP response */
+ if (STATE_SETUP == c->state) {
+ const char* token_state = NULL;
+ const char* pc = NULL;
+ c->session = pa_xstrdup(pa_headerlist_gets(c->response_headers, "Session"));
+ c->transport = pa_xstrdup(pa_headerlist_gets(c->response_headers, "Transport"));
+
+ if (!c->session || !c->transport) {
+ pa_headerlist_free(c->response_headers);
+ c->response_headers = NULL;
+ pa_log("Invalid SETUP response.");
+ return;
+ }
+
+ /* Now parse out the server port component of the response. */
+ while ((token = pa_split(c->transport, delimiters, &token_state))) {
+ if ((pc = strstr(token, "="))) {
+ if (0 == strncmp(token, "server_port", 11)) {
+ pa_atou(pc+1, (uint32_t*)(&c->rtp_port));
+ pa_xfree(token);
+ break;
+ }
+ }
+ pa_xfree(token);
+ }
+ if (0 == c->rtp_port) {
+ /* Error no server_port in response */
+ pa_headerlist_free(c->response_headers);
+ c->response_headers = NULL;
+ pa_log("Invalid SETUP response (no port number).");
+ return;
+ }
+ }
+
+ /* Call our callback */
+ c->callback(c, c->state, c->response_headers, c->userdata);
+
+ pa_headerlist_free(c->response_headers);
+ c->response_headers = NULL;
+}
+
+
+static void line_callback(pa_ioline *line, const char *s, void *userdata) {
+ char *delimpos;
+ char *s2, *s2p;
+
+ pa_rtsp_client *c = userdata;
+ pa_assert(line);
+ pa_assert(c);
+ pa_assert(c->callback);
+
+ if (!s) {
+ /* Keep the ioline/iochannel open as they will be freed automatically */
+ c->ioline = NULL;
+ c->io = NULL;
+ c->callback(c, STATE_DISCONNECTED, NULL, c->userdata);
+ return;
+ }
+
+ s2 = pa_xstrdup(s);
+ /* Trim trailing carriage returns */
+ s2p = s2 + strlen(s2) - 1;
+ while (s2p >= s2 && '\r' == *s2p) {
+ *s2p = '\0';
+ s2p -= 1;
+ }
+ if (c->waiting && 0 == strcmp("RTSP/1.0 200 OK", s2)) {
+ c->waiting = 0;
+ pa_assert(!c->response_headers);
+ c->response_headers = pa_headerlist_new();
+ goto exit;
+ }
+ if (c->waiting) {
+ pa_log_warn("Unexpected response: %s", s2);
+ goto exit;;
+ }
+ if (!strlen(s2)) {
+ /* End of headers */
+ /* We will have a header left from our looping itteration, so add it in :) */
+ if (c->last_header) {
+ /* This is not a continuation header so let's dump it into our proplist */
+ pa_headerlist_puts(c->response_headers, c->last_header, pa_strbuf_tostring_free(c->header_buffer));
+ pa_xfree(c->last_header);
+ c->last_header = NULL;
+ c->header_buffer= NULL;
+ }
+
+ pa_log_debug("Full response received. Dispatching");
+ headers_read(c);
+ c->waiting = 1;
+ goto exit;
+ }
+
+ /* Read and parse a header (we know it's not empty) */
+ /* TODO: Move header reading into the headerlist. */
+
+ /* If the first character is a space, it's a continuation header */
+ if (c->last_header && ' ' == s2[0]) {
+ pa_assert(c->header_buffer);
+
+ /* Add this line to the buffer (sans the space. */
+ pa_strbuf_puts(c->header_buffer, &(s2[1]));
+ goto exit;
+ }
+
+ if (c->last_header) {
+ /* This is not a continuation header so let's dump the full
+ header/value into our proplist */
+ pa_headerlist_puts(c->response_headers, c->last_header, pa_strbuf_tostring_free(c->header_buffer));
+ pa_xfree(c->last_header);
+ c->last_header = NULL;
+ c->header_buffer = NULL;
+ }
+
+ delimpos = strstr(s2, ":");
+ if (!delimpos) {
+ pa_log_warn("Unexpected response when expecting header: %s", s);
+ goto exit;
+ }
+
+ pa_assert(!c->header_buffer);
+ pa_assert(!c->last_header);
+
+ c->header_buffer = pa_strbuf_new();
+ if (strlen(delimpos) > 1) {
+ /* Cut our line off so we can copy the header name out */
+ *delimpos++ = '\0';
+
+ /* Trim the front of any spaces */
+ while (' ' == *delimpos)
+ ++delimpos;
+
+ pa_strbuf_puts(c->header_buffer, delimpos);
+ } else {
+ /* Cut our line off so we can copy the header name out */
+ *delimpos = '\0';
+ }
+
+ /* Save the header name */
+ c->last_header = pa_xstrdup(s2);
+ exit:
+ pa_xfree(s2);
+}
+
+
+static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
+ pa_rtsp_client *c = userdata;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+ struct sockaddr_in6 in6;
+ } sa;
+ socklen_t sa_len = sizeof(sa);
+
+ pa_assert(sc);
+ pa_assert(c);
+ pa_assert(STATE_CONNECT == c->state);
+ pa_assert(c->sc == sc);
+ pa_socket_client_unref(c->sc);
+ c->sc = NULL;
+
+ if (!io) {
+ pa_log("Connection failed: %s", pa_cstrerror(errno));
+ return;
+ }
+ pa_assert(!c->io);
+ c->io = io;
+
+ c->ioline = pa_ioline_new(io);
+ pa_ioline_set_callback(c->ioline, line_callback, c);
+
+ /* Get the local IP address for use externally */
+ if (0 == getsockname(pa_iochannel_get_recv_fd(io), &sa.sa, &sa_len)) {
+ char buf[INET6_ADDRSTRLEN];
+ const char *res = NULL;
+
+ if (AF_INET == sa.sa.sa_family) {
+ if ((res = inet_ntop(sa.sa.sa_family, &sa.in.sin_addr, buf, sizeof(buf)))) {
+ c->localip = pa_xstrdup(res);
+ }
+ } else if (AF_INET6 == sa.sa.sa_family) {
+ if ((res = inet_ntop(AF_INET6, &sa.in6.sin6_addr, buf, sizeof(buf)))) {
+ c->localip = pa_sprintf_malloc("[%s]", res);
+ }
+ }
+ }
+ pa_log_debug("Established RTSP connection from local ip %s", c->localip);
+
+ if (c->callback)
+ c->callback(c, c->state, NULL, c->userdata);
+}
+
+int pa_rtsp_connect(pa_rtsp_client *c) {
+ pa_assert(c);
+ pa_assert(!c->sc);
+
+ pa_xfree(c->session);
+ c->session = NULL;
+
+ if (!(c->sc = pa_socket_client_new_string(c->mainloop, c->hostname, c->port))) {
+ pa_log("failed to connect to server '%s:%d'", c->hostname, c->port);
+ return -1;
+ }
+
+ pa_socket_client_set_callback(c->sc, on_connection, c);
+ c->waiting = 1;
+ c->state = STATE_CONNECT;
+ return 0;
+}
+
+void pa_rtsp_set_callback(pa_rtsp_client *c, pa_rtsp_cb_t callback, void *userdata) {
+ pa_assert(c);
+
+ c->callback = callback;
+ c->userdata = userdata;
+}
+
+void pa_rtsp_disconnect(pa_rtsp_client *c) {
+ pa_assert(c);
+
+ if (c->io)
+ pa_iochannel_free(c->io);
+ c->io = NULL;
+}
+
+
+const char* pa_rtsp_localip(pa_rtsp_client* c) {
+ pa_assert(c);
+
+ return c->localip;
+}
+
+uint32_t pa_rtsp_serverport(pa_rtsp_client* c) {
+ pa_assert(c);
+
+ return c->rtp_port;
+}
+
+void pa_rtsp_set_url(pa_rtsp_client* c, const char* url) {
+ pa_assert(c);
+
+ c->url = pa_xstrdup(url);
+}
+
+void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value)
+{
+ pa_assert(c);
+ pa_assert(key);
+ pa_assert(value);
+
+ pa_headerlist_puts(c->headers, key, value);
+}
+
+void pa_rtsp_remove_header(pa_rtsp_client *c, const char* key)
+{
+ pa_assert(c);
+ pa_assert(key);
+
+ pa_headerlist_remove(c->headers, key);
+}
+
+static int rtsp_exec(pa_rtsp_client* c, const char* cmd,
+ const char* content_type, const char* content,
+ int expect_response,
+ pa_headerlist* headers) {
+ pa_strbuf* buf;
+ char* hdrs;
+ ssize_t l;
+
+ pa_assert(c);
+ pa_assert(c->url);
+
+ if (!cmd)
+ return -1;
+
+ pa_log_debug("Sending command: %s", cmd);
+
+ buf = pa_strbuf_new();
+ pa_strbuf_printf(buf, "%s %s RTSP/1.0\r\nCSeq: %d\r\n", cmd, c->url, ++c->cseq);
+ if (c->session)
+ pa_strbuf_printf(buf, "Session: %s\r\n", c->session);
+
+ /* Add the headers */
+ if (headers) {
+ hdrs = pa_headerlist_to_string(headers);
+ pa_strbuf_puts(buf, hdrs);
+ pa_xfree(hdrs);
+ }
+
+ if (content_type && content) {
+ pa_strbuf_printf(buf, "Content-Type: %s\r\nContent-Length: %d\r\n",
+ content_type, (int)strlen(content));
+ }
+
+ pa_strbuf_printf(buf, "User-Agent: %s\r\n", c->useragent);
+
+ if (c->headers) {
+ hdrs = pa_headerlist_to_string(c->headers);
+ pa_strbuf_puts(buf, hdrs);
+ pa_xfree(hdrs);
+ }
+
+ pa_strbuf_puts(buf, "\r\n");
+
+ if (content_type && content) {
+ pa_strbuf_puts(buf, content);
+ }
+
+ /* Our packet is created... now we can send it :) */
+ hdrs = pa_strbuf_tostring_free(buf);
+ /*pa_log_debug("Submitting request:");
+ pa_log_debug(hdrs);*/
+ l = pa_iochannel_write(c->io, hdrs, strlen(hdrs));
+ pa_xfree(hdrs);
+
+ return 0;
+}
+
+
+int pa_rtsp_announce(pa_rtsp_client *c, const char* sdp) {
+ pa_assert(c);
+ if (!sdp)
+ return -1;
+
+ c->state = STATE_ANNOUNCE;
+ return rtsp_exec(c, "ANNOUNCE", "application/sdp", sdp, 1, NULL);
+}
+
+
+int pa_rtsp_setup(pa_rtsp_client* c) {
+ pa_headerlist* headers;
+ int rv;
+
+ pa_assert(c);
+
+ headers = pa_headerlist_new();
+ pa_headerlist_puts(headers, "Transport", "RTP/AVP/TCP;unicast;interleaved=0-1;mode=record");
+
+ c->state = STATE_SETUP;
+ rv = rtsp_exec(c, "SETUP", NULL, NULL, 1, headers);
+ pa_headerlist_free(headers);
+ return rv;
+}
+
+
+int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime) {
+ pa_headerlist* headers;
+ int rv;
+ char *info;
+
+ pa_assert(c);
+ if (!c->session) {
+ /* No seesion in progres */
+ return -1;
+ }
+
+ /* Todo: Generate these values randomly as per spec */
+ *seq = *rtptime = 0;
+
+ headers = pa_headerlist_new();
+ pa_headerlist_puts(headers, "Range", "npt=0-");
+ info = pa_sprintf_malloc("seq=%u;rtptime=%u", *seq, *rtptime);
+ pa_headerlist_puts(headers, "RTP-Info", info);
+ pa_xfree(info);
+
+ c->state = STATE_RECORD;
+ rv = rtsp_exec(c, "RECORD", NULL, NULL, 1, headers);
+ pa_headerlist_free(headers);
+ return rv;
+}
+
+
+int pa_rtsp_teardown(pa_rtsp_client *c) {
+ pa_assert(c);
+
+ c->state = STATE_TEARDOWN;
+ return rtsp_exec(c, "TEARDOWN", NULL, NULL, 0, NULL);
+}
+
+
+int pa_rtsp_setparameter(pa_rtsp_client *c, const char* param) {
+ pa_assert(c);
+ if (!param)
+ return -1;
+
+ c->state = STATE_SET_PARAMETER;
+ return rtsp_exec(c, "SET_PARAMETER", "text/parameters", param, 1, NULL);
+}
+
+
+int pa_rtsp_flush(pa_rtsp_client *c, uint16_t seq, uint32_t rtptime) {
+ pa_headerlist* headers;
+ int rv;
+ char *info;
+
+ pa_assert(c);
+
+ headers = pa_headerlist_new();
+ info = pa_sprintf_malloc("seq=%u;rtptime=%u", seq, rtptime);
+ pa_headerlist_puts(headers, "RTP-Info", info);
+ pa_xfree(info);
+
+ c->state = STATE_FLUSH;
+ rv = rtsp_exec(c, "FLUSH", NULL, NULL, 1, headers);
+ pa_headerlist_free(headers);
+ return rv;
+}
diff --git a/src/modules/rtp/rtsp_client.h b/src/modules/rtp/rtsp_client.h
new file mode 100644
index 00000000..88fb3839
--- /dev/null
+++ b/src/modules/rtp/rtsp_client.h
@@ -0,0 +1,73 @@
+#ifndef foortspclienthfoo
+#define foortspclienthfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2008 Colin Guthrie
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License,
+ or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#include <inttypes.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+#include <pulsecore/memblockq.h>
+#include <pulsecore/memchunk.h>
+#include <pulsecore/socket-client.h>
+#include <pulse/mainloop-api.h>
+
+#include "headerlist.h"
+
+typedef struct pa_rtsp_client pa_rtsp_client;
+typedef enum {
+ STATE_CONNECT,
+ STATE_ANNOUNCE,
+ STATE_SETUP,
+ STATE_RECORD,
+ STATE_FLUSH,
+ STATE_TEARDOWN,
+ STATE_SET_PARAMETER,
+ STATE_DISCONNECTED
+} pa_rtsp_state;
+typedef void (*pa_rtsp_cb_t)(pa_rtsp_client *c, pa_rtsp_state state, pa_headerlist* hl, void *userdata);
+
+pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char* hostname, uint16_t port, const char* useragent);
+void pa_rtsp_client_free(pa_rtsp_client* c);
+
+int pa_rtsp_connect(pa_rtsp_client* c);
+void pa_rtsp_set_callback(pa_rtsp_client *c, pa_rtsp_cb_t callback, void *userdata);
+
+void pa_rtsp_disconnect(pa_rtsp_client* c);
+
+const char* pa_rtsp_localip(pa_rtsp_client* c);
+uint32_t pa_rtsp_serverport(pa_rtsp_client* c);
+void pa_rtsp_set_url(pa_rtsp_client* c, const char* url);
+void pa_rtsp_add_header(pa_rtsp_client *c, const char* key, const char* value);
+void pa_rtsp_remove_header(pa_rtsp_client *c, const char* key);
+
+int pa_rtsp_announce(pa_rtsp_client* c, const char* sdp);
+
+int pa_rtsp_setup(pa_rtsp_client* c);
+int pa_rtsp_record(pa_rtsp_client* c, uint16_t* seq, uint32_t* rtptime);
+int pa_rtsp_teardown(pa_rtsp_client* c);
+
+int pa_rtsp_setparameter(pa_rtsp_client* c, const char* param);
+int pa_rtsp_flush(pa_rtsp_client* c, uint16_t seq, uint32_t rtptime);
+
+#endif
diff --git a/src/modules/rtp/sap.c b/src/modules/rtp/sap.c
index 5d9b58fa..b0c95aa5 100644
--- a/src/modules/rtp/sap.c
+++ b/src/modules/rtp/sap.c
@@ -76,7 +76,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) {
socklen_t salen = sizeof(sa_buf);
struct iovec iov[4];
struct msghdr m;
- int k;
+ ssize_t k;
if (getsockname(c->fd, sa, &salen) < 0) {
pa_log("getsockname() failed: %s\n", pa_cstrerror(errno));
@@ -94,7 +94,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) {
iov[0].iov_len = sizeof(header);
iov[1].iov_base = sa->sa_family == AF_INET ? (void*) &((struct sockaddr_in*) sa)->sin_addr : (void*) &((struct sockaddr_in6*) sa)->sin6_addr;
- iov[1].iov_len = sa->sa_family == AF_INET ? 4 : 16;
+ iov[1].iov_len = sa->sa_family == AF_INET ? 4U : 16U;
iov[2].iov_base = (char*) MIME_TYPE;
iov[2].iov_len = sizeof(MIME_TYPE);
@@ -113,7 +113,7 @@ int pa_sap_send(pa_sap_context *c, pa_bool_t goodbye) {
if ((k = sendmsg(c->fd, &m, MSG_DONTWAIT)) < 0)
pa_log_warn("sendmsg() failed: %s\n", pa_cstrerror(errno));
- return k;
+ return (int) k;
}
pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) {
@@ -128,10 +128,10 @@ pa_sap_context* pa_sap_context_init_recv(pa_sap_context *c, int fd) {
int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
struct msghdr m;
struct iovec iov;
- int size, k;
+ int size;
char *buf = NULL, *e;
uint32_t header;
- int six, ac;
+ unsigned six, ac, k;
ssize_t r;
pa_assert(c);
@@ -142,11 +142,11 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
goto fail;
}
- buf = pa_xnew(char, size+1);
+ buf = pa_xnew(char, (unsigned) size+1);
buf[size] = 0;
iov.iov_base = buf;
- iov.iov_len = size;
+ iov.iov_len = (size_t) size;
m.msg_name = NULL;
m.msg_namelen = 0;
@@ -184,21 +184,21 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
goto fail;
}
- six = (header >> 28) & 1;
- ac = (header >> 16) & 0xFF;
+ six = (header >> 28) & 1U;
+ ac = (header >> 16) & 0xFFU;
- k = 4 + (six ? 16 : 4) + ac*4;
- if (size < k) {
+ k = 4 + (six ? 16U : 4U) + ac*4U;
+ if ((unsigned) size < k) {
pa_log_warn("SAP packet too short (AD).");
goto fail;
}
e = buf + k;
- size -= k;
+ size -= (int) k;
if ((unsigned) size >= sizeof(MIME_TYPE) && !strcmp(e, MIME_TYPE)) {
e += sizeof(MIME_TYPE);
- size -= sizeof(MIME_TYPE);
+ size -= (int) sizeof(MIME_TYPE);
} else if ((unsigned) size < sizeof(PA_SDP_HEADER)-1 || strncmp(e, PA_SDP_HEADER, sizeof(PA_SDP_HEADER)-1)) {
pa_log_warn("Invalid SDP header.");
goto fail;
@@ -207,7 +207,7 @@ int pa_sap_recv(pa_sap_context *c, pa_bool_t *goodbye) {
if (c->sdp_data)
pa_xfree(c->sdp_data);
- c->sdp_data = pa_xstrndup(e, size);
+ c->sdp_data = pa_xstrndup(e, (unsigned) size);
pa_xfree(buf);
*goodbye = !!((header >> 26) & 1);
diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c
index cef90433..59989e1a 100644
--- a/src/modules/rtp/sdp.c
+++ b/src/modules/rtp/sdp.c
@@ -55,7 +55,7 @@ char *pa_sdp_build(int af, const void *src, const void *dst, const char *name, u
if (!(u = pa_get_user_name(un, sizeof(un))))
u = "-";
- ntp = time(NULL) + 2208988800U;
+ ntp = (uint32_t) time(NULL) + 2208988800U;
pa_assert_se(a = inet_ntop(af, src, buf_src, sizeof(buf_src)));
pa_assert_se(a = inet_ntop(af, dst, buf_dst, sizeof(buf_dst)));
@@ -99,10 +99,10 @@ static pa_sample_spec *parse_sdp_sample_spec(pa_sample_spec *ss, char *c) {
return NULL;
if (sscanf(c, "%u/%u", &rate, &channels) == 2) {
- ss->rate = rate;
- ss->channels = channels;
+ ss->rate = (uint32_t) rate;
+ ss->channels = (uint8_t) channels;
} else if (sscanf(c, "%u", &rate) == 2) {
- ss->rate = rate;
+ ss->rate = (uint32_t) rate;
ss->channels = 1;
} else
return NULL;
diff --git a/src/pulse/channelmap.c b/src/pulse/channelmap.c
index db0c4b3f..fd313bd3 100644
--- a/src/pulse/channelmap.c
+++ b/src/pulse/channelmap.c
@@ -198,10 +198,11 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
pa_assert(m);
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
+ pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
- m->channels = channels;
+ m->channels = (uint8_t) channels;
switch (def) {
case PA_CHANNEL_MAP_AIFF:
@@ -287,9 +288,6 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
case PA_CHANNEL_MAP_AUX: {
unsigned i;
- if (channels >= PA_CHANNELS_MAX)
- return NULL;
-
for (i = 0; i < channels; i++)
m->map[i] = PA_CHANNEL_POSITION_AUX0 + i;
@@ -391,7 +389,7 @@ pa_channel_map* pa_channel_map_init_auto(pa_channel_map *m, unsigned channels, p
default:
- return NULL;
+ pa_assert_not_reached();
}
}
@@ -401,6 +399,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels,
pa_assert(m);
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
+ pa_assert(def < PA_CHANNEL_MAP_DEF_MAX);
pa_channel_map_init(m);
@@ -415,7 +414,7 @@ pa_channel_map* pa_channel_map_init_extend(pa_channel_map *m, unsigned channels,
i++;
}
- m->channels = channels;
+ m->channels = (uint8_t) channels;
return m;
}
@@ -460,13 +459,20 @@ int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) {
char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
unsigned channel;
- int first = 1;
+ pa_bool_t first = TRUE;
char *e;
pa_assert(s);
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++) {
@@ -475,7 +481,7 @@ char* pa_channel_map_snprint(char *s, size_t l, const pa_channel_map *map) {
pa_channel_position_to_string(map->map[channel]));
e = strchr(e, 0);
- first = 0;
+ first = FALSE;
}
return s;
@@ -489,7 +495,7 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *rmap, const char *s) {
pa_assert(rmap);
pa_assert(s);
- memset(&map, 0, sizeof(map));
+ pa_channel_map_init(&map);
if (strcmp(s, "stereo") == 0) {
map.channels = 2;
@@ -552,11 +558,22 @@ int pa_channel_map_valid(const pa_channel_map *map) {
if (map->channels <= 0 || map->channels > PA_CHANNELS_MAX)
return 0;
- for (c = 0; c < map->channels; c++) {
-
- if (map->map[c] < 0 ||map->map[c] >= PA_CHANNEL_POSITION_MAX)
+ for (c = 0; c < map->channels; c++)
+ if (map->map[c] < 0 || map->map[c] >= PA_CHANNEL_POSITION_MAX)
return 0;
- }
return 1;
}
+
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) {
+ 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 7c32b868..d7d19d79 100644
--- a/src/pulse/channelmap.h
+++ b/src/pulse/channelmap.h
@@ -142,24 +142,42 @@ typedef enum pa_channel_position {
/** A list of channel mapping definitions for pa_channel_map_init_auto() */
typedef enum pa_channel_map_def {
- PA_CHANNEL_MAP_AIFF, /**< The mapping from RFC3551, which is based on AIFF-C */
- PA_CHANNEL_MAP_ALSA, /**< The default mapping used by ALSA */
- PA_CHANNEL_MAP_AUX, /**< Only aux channels */
- PA_CHANNEL_MAP_WAVEEX, /**< Microsoft's WAVEFORMATEXTENSIBLE mapping */
- PA_CHANNEL_MAP_OSS, /**< The default channel mapping used by OSS as defined in the OSS 4.0 API specs */
+ PA_CHANNEL_MAP_AIFF,
+ /**< The mapping from RFC3551, which is based on AIFF-C */
- PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF /**< The default channel map */
+ PA_CHANNEL_MAP_ALSA,
+ /**< The default mapping used by ALSA */
+
+ PA_CHANNEL_MAP_AUX,
+ /**< Only aux channels */
+
+ PA_CHANNEL_MAP_WAVEEX,
+ /**< Microsoft's WAVEFORMATEXTENSIBLE mapping */
+
+ PA_CHANNEL_MAP_OSS,
+ /**< The default channel mapping used by OSS as defined in the OSS 4.0 API specs */
+
+ /**< Upper limit of valid channel mapping definitions */
+ PA_CHANNEL_MAP_DEF_MAX,
+
+ PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF
+ /**< The default channel map */
} pa_channel_map_def_t;
/** A channel map which can be used to attach labels to specific
* channels of a stream. These values are relevant for conversion and
* mixing of streams */
typedef struct pa_channel_map {
- uint8_t channels; /**< Number of channels */
- pa_channel_position_t map[PA_CHANNELS_MAX]; /**< Channel labels */
+ uint8_t channels;
+ /**< Number of channels */
+
+ pa_channel_position_t map[PA_CHANNELS_MAX];
+ /**< 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 */
@@ -186,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 */
@@ -198,9 +220,13 @@ pa_channel_map *pa_channel_map_parse(pa_channel_map *map, const char *s);
/** Compare two channel maps. Return 1 if both match. */
int pa_channel_map_equal(const pa_channel_map *a, const pa_channel_map *b) PA_GCC_PURE;
-/** Return non-zero of the specified channel map is considered valid */
+/** Return non-zero if the specified channel map is considered valid */
int pa_channel_map_valid(const pa_channel_map *map) PA_GCC_PURE;
+/** Return non-zero if the specified channel map is compatible with
+ * the specified sample spec. \since 0.9.12 */
+int pa_channel_map_compatible(const pa_channel_map *map, const pa_sample_spec *ss) PA_GCC_PURE;
+
PA_C_DECL_END
#endif
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 5be4078b..3145d9c8 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -81,8 +81,6 @@
#include "context.h"
-#define AUTOSPAWN_LOCK "autospawn.lock"
-
void pa_command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata);
static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
@@ -99,23 +97,6 @@ static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = {
[PA_COMMAND_SUBSCRIBE_EVENT] = pa_command_subscribe_event,
[PA_COMMAND_EXTENSION] = pa_command_extension
};
-
-static void unlock_autospawn_lock_file(pa_context *c) {
- pa_assert(c);
-
- if (c->autospawn_lock_fd >= 0) {
- char *lf;
-
- if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
- pa_log_warn(_("Cannot unlock autospawn because runtime path is no more."));
-
- pa_unlock_lockfile(lf, c->autospawn_lock_fd);
- pa_xfree(lf);
-
- c->autospawn_lock_fd = -1;
- }
-}
-
static void context_free(pa_context *c);
pa_context *pa_context_new(pa_mainloop_api *mainloop, const char *name) {
@@ -174,11 +155,12 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
c->is_local = FALSE;
c->server_list = NULL;
c->server = NULL;
- c->autospawn_lock_fd = -1;
- memset(&c->spawn_api, 0, sizeof(c->spawn_api));
- c->do_autospawn = FALSE;
+
c->do_shm = FALSE;
+ c->do_autospawn = FALSE;
+ memset(&c->spawn_api, 0, sizeof(c->spawn_api));
+
#ifndef MSG_NOSIGNAL
#ifdef SIGPIPE
pa_check_signal_is_blocked(SIGPIPE);
@@ -192,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(0);
+ c->mempool = pa_mempool_new(FALSE, c->conf->shm_size);
if (!c->mempool) {
context_free(c);
@@ -246,8 +228,6 @@ static void context_free(pa_context *c) {
context_unlink(c);
- unlock_autospawn_lock_file(c);
-
if (c->record_streams)
pa_dynarray_free(c->record_streams, NULL, NULL);
if (c->playback_streams)
@@ -407,11 +387,11 @@ int pa_context_handle_error(pa_context *c, uint32_t command, pa_tagstruct *t, pa
err = PA_ERR_UNKNOWN;
if (fail) {
- pa_context_fail(c, err);
+ pa_context_fail(c, (int) err);
return -1;
}
- pa_context_set_error(c, err);
+ pa_context_set_error(c, (int) err);
return 0;
}
@@ -433,7 +413,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
switch(c->state) {
case PA_CONTEXT_AUTHORIZING: {
pa_tagstruct *reply;
- pa_bool_t shm_on_remote;
+ pa_bool_t shm_on_remote = FALSE;
if (pa_tagstruct_getu32(t, &c->version) < 0 ||
!pa_tagstruct_eof(t)) {
@@ -571,31 +551,89 @@ static void setup_context(pa_context *c, pa_iochannel *io) {
pa_context_unref(c);
}
-static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
+static char *get_old_legacy_runtime_dir(void) {
+ char *p, u[128];
+ struct stat st;
-#ifndef OS_IS_WIN32
+ if (!pa_get_user_name(u, sizeof(u)))
+ return NULL;
-static int context_connect_spawn(pa_context *c) {
- pid_t pid;
- int status, r;
- int fds[2] = { -1, -1} ;
- pa_iochannel *io;
+ p = pa_sprintf_malloc("/tmp/pulse-%s", u);
- if (getuid() == 0)
- return -1;
+ if (stat(p, &st) < 0) {
+ pa_xfree(p);
+ return NULL;
+ }
- pa_context_ref(c);
+ if (st.st_uid != getuid()) {
+ pa_xfree(p);
+ return NULL;
+ }
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
- pa_log_error(_("socketpair(): %s"), pa_cstrerror(errno));
- pa_context_fail(c, PA_ERR_INTERNAL);
- goto fail;
+ return p;
+}
+
+static char *get_very_old_legacy_runtime_dir(void) {
+ char *p, h[128];
+ struct stat st;
+
+ if (!pa_get_home_dir(h, sizeof(h)))
+ return NULL;
+
+ p = pa_sprintf_malloc("%s/.pulse", h);
+
+ if (stat(p, &st) < 0) {
+ pa_xfree(p);
+ return NULL;
+ }
+
+ if (st.st_uid != getuid()) {
+ pa_xfree(p);
+ return NULL;
}
- pa_make_fd_cloexec(fds[0]);
+ return p;
+}
- pa_make_socket_low_delay(fds[0]);
- pa_make_socket_low_delay(fds[1]);
+
+static pa_strlist *prepend_per_user(pa_strlist *l) {
+ char *ufn;
+ static char *legacy_dir;
+
+ /* The very old per-user instance path (< 0.9.11). This is supported only to ease upgrades */
+ if ((legacy_dir = get_very_old_legacy_runtime_dir())) {
+ char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
+ l = pa_strlist_prepend(l, p);
+ pa_xfree(p);
+ pa_xfree(legacy_dir);
+ }
+
+ /* The old per-user instance path (< 0.9.12). This is supported only to ease upgrades */
+ if ((legacy_dir = get_old_legacy_runtime_dir())) {
+ char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
+ l = pa_strlist_prepend(l, p);
+ pa_xfree(p);
+ pa_xfree(legacy_dir);
+ }
+
+ /* The per-user instance */
+ if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
+ l = pa_strlist_prepend(l, ufn);
+ pa_xfree(ufn);
+ }
+
+ return l;
+}
+
+#ifndef OS_IS_WIN32
+
+static int context_autospawn(pa_context *c) {
+ pid_t pid;
+ int status, r;
+
+ pa_log_debug("Trying to autospawn...");
+
+ pa_context_ref(c);
if (c->spawn_api.prefork)
c->spawn_api.prefork();
@@ -611,31 +649,22 @@ static int context_connect_spawn(pa_context *c) {
} else if (!pid) {
/* Child */
- char t[128];
const char *state = NULL;
#define MAX_ARGS 64
const char * argv[MAX_ARGS+1];
int n;
- char *f;
-
- pa_close_all(fds[1], -1);
-
- f = pa_sprintf_malloc("%i", fds[1]);
- pa_set_env("PULSE_PASSED_FD", f);
- pa_xfree(f);
if (c->spawn_api.atfork)
c->spawn_api.atfork();
+ pa_close_all(-1);
+
/* Setup argv */
n = 0;
argv[n++] = c->conf->daemon_binary;
- argv[n++] = "--daemonize=yes";
-
- pa_snprintf(t, sizeof(t), "-Lmodule-native-protocol-fd fd=%i", fds[1]);
- argv[n++] = strdup(t);
+ argv[n++] = "--start";
while (n < MAX_ARGS) {
char *a;
@@ -655,14 +684,13 @@ static int context_connect_spawn(pa_context *c) {
/* Parent */
- pa_assert_se(pa_close(fds[1]) == 0);
- fds[1] = -1;
-
- r = waitpid(pid, &status, 0);
-
if (c->spawn_api.postfork)
c->spawn_api.postfork();
+ do {
+ r = waitpid(pid, &status, 0);
+ } while (r < 0 && errno == EINTR);
+
if (r < 0) {
pa_log(_("waitpid(): %s"), pa_cstrerror(errno));
pa_context_fail(c, PA_ERR_INTERNAL);
@@ -672,21 +700,11 @@ static int context_connect_spawn(pa_context *c) {
goto fail;
}
- c->is_local = TRUE;
-
- unlock_autospawn_lock_file(c);
-
- io = pa_iochannel_new(c->mainloop, fds[0], fds[0]);
- setup_context(c, io);
-
pa_context_unref(c);
return 0;
fail:
- pa_close_pipe(fds);
-
- unlock_autospawn_lock_file(c);
pa_context_unref(c);
@@ -695,6 +713,8 @@ fail:
#endif /* OS_IS_WIN32 */
+static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userdata);
+
static int try_next_connection(pa_context *c) {
char *u = NULL;
int r = -1;
@@ -712,8 +732,18 @@ static int try_next_connection(pa_context *c) {
#ifndef OS_IS_WIN32
if (c->do_autospawn) {
- r = context_connect_spawn(c);
- goto finish;
+
+ if ((r = context_autospawn(c)) < 0)
+ goto finish;
+
+ /* Autospawn only once */
+ c->do_autospawn = FALSE;
+
+ /* Connect only to per-user sockets this time */
+ c->server_list = prepend_per_user(c->server_list);
+
+ /* Retry connection */
+ continue;
}
#endif
@@ -768,36 +798,12 @@ static void on_connection(pa_socket_client *client, pa_iochannel*io, void *userd
goto finish;
}
- unlock_autospawn_lock_file(c);
setup_context(c, io);
finish:
pa_context_unref(c);
}
-
-static char *get_legacy_runtime_dir(void) {
- char *p, u[128];
- struct stat st;
-
- if (!pa_get_user_name(u, sizeof(u)))
- return NULL;
-
- p = pa_sprintf_malloc("/tmp/pulse-%s", u);
-
- if (stat(p, &st) < 0) {
- pa_xfree(p);
- return NULL;
- }
-
- if (st.st_uid != getuid()) {
- pa_xfree(p);
- return NULL;
- }
-
- return p;
-}
-
int pa_context_connect(
pa_context *c,
const char *server,
@@ -825,12 +831,13 @@ int pa_context_connect(
pa_context_fail(c, PA_ERR_INVALIDSERVER);
goto finish;
}
+
} else {
- char *d, *ufn;
- static char *legacy_dir;
+ char *d;
/* Prepend in reverse order */
+ /* Follow the X display */
if ((d = getenv("DISPLAY"))) {
char *e;
d = pa_xstrdup(d);
@@ -843,43 +850,27 @@ int pa_context_connect(
pa_xfree(d);
}
- c->server_list = pa_strlist_prepend(c->server_list, "tcp6:localhost");
- c->server_list = pa_strlist_prepend(c->server_list, "tcp4:localhost");
+ /* Add TCP/IP on the localhost */
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp6:[::1]");
+ c->server_list = pa_strlist_prepend(c->server_list, "tcp4:127.0.0.1");
- /* The system wide instance */
+ /* The system wide instance via PF_LOCAL */
c->server_list = pa_strlist_prepend(c->server_list, PA_SYSTEM_RUNTIME_PATH PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET);
- /* The old per-user instance path. This is supported only to ease upgrades */
- if ((legacy_dir = get_legacy_runtime_dir())) {
- char *p = pa_sprintf_malloc("%s" PA_PATH_SEP PA_NATIVE_DEFAULT_UNIX_SOCKET, legacy_dir);
- c->server_list = pa_strlist_prepend(c->server_list, p);
- pa_xfree(p);
- pa_xfree(legacy_dir);
- }
+ /* The user instance via PF_LOCAL */
+ c->server_list = prepend_per_user(c->server_list);
- /* The per-user instance */
- if ((ufn = pa_runtime_path(PA_NATIVE_DEFAULT_UNIX_SOCKET))) {
- c->server_list = pa_strlist_prepend(c->server_list, ufn);
- pa_xfree(ufn);
- }
-
- /* Wrap the connection attempts in a single transaction for sane autospawn locking */
+ /* Set up autospawning */
if (!(flags & PA_CONTEXT_NOAUTOSPAWN) && c->conf->autospawn) {
- char *lf;
- if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
- pa_context_fail(c, PA_ERR_ACCESS);
- goto finish;
- }
+ if (getuid() == 0)
+ pa_log_debug("Not doing autospawn since we are root.");
+ else {
+ c->do_autospawn = TRUE;
- pa_assert(c->autospawn_lock_fd <= 0);
- c->autospawn_lock_fd = pa_lock_lockfile(lf);
- pa_xfree(lf);
-
- if (api)
- c->spawn_api = *api;
-
- c->do_autospawn = TRUE;
+ if (api)
+ c->spawn_api = *api;
+ }
}
}
@@ -938,11 +929,11 @@ int pa_context_is_pending(pa_context *c) {
static void set_dispatch_callbacks(pa_operation *o);
-static void pdispatch_drain_callback(PA_GCC_UNUSED pa_pdispatch*pd, void *userdata) {
+static void pdispatch_drain_callback(pa_pdispatch*pd, void *userdata) {
set_dispatch_callbacks(userdata);
}
-static void pstream_drain_callback(PA_GCC_UNUSED pa_pstream *s, void *userdata) {
+static void pstream_drain_callback(pa_pstream *s, void *userdata) {
set_dispatch_callbacks(userdata);
}
@@ -994,7 +985,7 @@ pa_operation* pa_context_drain(pa_context *c, pa_context_notify_cb_t cb, void *u
return o;
}
-void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_context_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@@ -1146,7 +1137,7 @@ const char* pa_context_get_server(pa_context *c) {
return c->server;
}
-uint32_t pa_context_get_protocol_version(PA_GCC_UNUSED pa_context *c) {
+uint32_t pa_context_get_protocol_version(pa_context *c) {
return PA_PROTOCOL_VERSION;
}
diff --git a/src/pulse/def.h b/src/pulse/def.h
index aa07d1c9..ace56574 100644
--- a/src/pulse/def.h
+++ b/src/pulse/def.h
@@ -57,7 +57,7 @@ static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x) {
/** The state of a stream */
typedef enum pa_stream_state {
- PA_STREAM_UNCONNECTED, /**< The stream is not yet connected to any sink or source */
+ PA_STREAM_UNCONNECTED, /**< The stream is not yet connected to any sink or source */
PA_STREAM_CREATING, /**< The stream is being created */
PA_STREAM_READY, /**< The stream is established, you may pass audio data to it now */
PA_STREAM_FAILED, /**< An error occured that made the stream invalid */
@@ -83,9 +83,15 @@ typedef enum pa_operation_state {
/** Some special flags for contexts. */
typedef enum pa_context_flags {
- PA_CONTEXT_NOAUTOSPAWN = 1 /**< Disabled autospawning of the PulseAudio daemon if required */
+ PA_CONTEXT_NOAUTOSPAWN = 1
+ /**< Disabled autospawning of the PulseAudio daemon if required */
} pa_context_flags_t;
+/** \cond fulldocs */
+/* Allow clients to check with #ifdef for those flags */
+#define PA_CONTEXT_NOAUTOSPAWN PA_CONTEXT_NOAUTOSPAWN
+/** \endcond */
+
/** The direction of a pa_stream object */
typedef enum pa_stream_direction {
PA_STREAM_NODIRECTION, /**< Invalid direction */
@@ -96,237 +102,226 @@ typedef enum pa_stream_direction {
/** Some special flags for stream connections. */
typedef enum pa_stream_flags {
- PA_STREAM_START_CORKED = 1, /**< Create the stream corked, requiring an explicit pa_stream_cork() call to uncork it. */
- PA_STREAM_INTERPOLATE_TIMING = 2, /**< Interpolate the latency for
- * this stream. When enabled,
- * pa_stream_get_latency() and
- * pa_stream_get_time() will try
- * to estimate the current
- * record/playback time based on
- * the local time that passed
- * since the last timing info
- * update. Using this option
- * has the advantage of not
- * requiring a whole roundtrip
- * when the current
- * playback/recording time is
- * needed. Consider using this
- * option when requesting
- * latency information
- * frequently. This is
- * especially useful on long
- * latency network
- * connections. It makes a lot
- * of sense to combine this
- * option with
- * PA_STREAM_AUTO_TIMING_UPDATE. */
- PA_STREAM_NOT_MONOTONIC = 4, /**< Don't force the time to
- * increase monotonically. If
- * this option is enabled,
- * pa_stream_get_time() will not
- * necessarily return always
- * monotonically increasing time
- * values on each call. This may
- * confuse applications which
- * cannot deal with time going
- * 'backwards', but has the
- * advantage that bad transport
- * latency estimations that
- * caused the time to to jump
- * ahead can be corrected
- * quickly, without the need to
- * wait. (Please note that this
- * flag was named
- * PA_STREAM_NOT_MONOTONOUS in
- * releases prior to 0.9.11. The
- * old name is still defined too,
- * for compatibility reasons. */
- PA_STREAM_AUTO_TIMING_UPDATE = 8, /**< If set timing update requests
- * are issued periodically
- * automatically. Combined with
- * PA_STREAM_INTERPOLATE_TIMING
- * you will be able to query the
- * current time and latency with
- * pa_stream_get_time() and
- * pa_stream_get_latency() at
- * all times without a packet
- * round trip.*/
- PA_STREAM_NO_REMAP_CHANNELS = 16, /**< Don't remap channels by
- * their name, instead map them
- * simply by their
- * index. Implies
- * PA_STREAM_NO_REMIX_CHANNELS. Only
- * supported when the server is
- * at least PA 0.9.8. It is
- * ignored on older
- * servers.\since 0.9.8 */
- PA_STREAM_NO_REMIX_CHANNELS = 32, /**< When remapping channels by
- * name, don't upmix or downmix
- * them to related
- * channels. Copy them into
- * matching channels of the
- * device 1:1. Only supported
- * when the server is at least
- * PA 0.9.8. It is ignored on
- * older servers. \since
- * 0.9.8 */
- PA_STREAM_FIX_FORMAT = 64, /**< Use the sample format of the
- * sink/device this stream is being
- * connected to, and possibly ignore
- * the format the sample spec contains
- * -- but you still have to pass a
- * valid value in it as a hint to
- * PulseAudio what would suit your
- * stream best. If this is used you
- * should query the used sample format
- * after creating the stream by using
- * pa_stream_get_sample_spec(). Also,
- * if you specified manual buffer
- * metrics it is recommended to update
- * them with
- * pa_stream_set_buffer_attr() to
- * compensate for the changed frame
- * sizes. Only supported when the
- * server is at least PA 0.9.8. It is
- * ignored on older servers. \since
- * 0.9.8 */
-
- PA_STREAM_FIX_RATE = 128, /**< Use the sample rate of the sink,
- * and possibly ignore the rate the
- * sample spec contains. Usage similar
- * to PA_STREAM_FIX_FORMAT.Only
- * supported when the server is at least
- * PA 0.9.8. It is ignored on older
- * servers. \since 0.9.8 */
-
- PA_STREAM_FIX_CHANNELS = 256, /**< Use the number of channels and
- * the channel map of the sink, and
- * possibly ignore the number of
- * channels and the map the sample spec
- * and the passed channel map
- * contains. Usage similar to
- * PA_STREAM_FIX_FORMAT. Only supported
- * when the server is at least PA
- * 0.9.8. It is ignored on older
- * servers. \since 0.9.8 */
- PA_STREAM_DONT_MOVE = 512, /**< Don't allow moving of this stream to
- * another sink/device. Useful if you use
- * any of the PA_STREAM_FIX_ flags and
- * want to make sure that resampling
- * never takes place -- which might
- * happen if the stream is moved to
- * another sink/source whith a different
- * sample spec/channel map. Only
- * supported when the server is at least
- * PA 0.9.8. It is ignored on older
- * servers. \since 0.9.8 */
- PA_STREAM_VARIABLE_RATE = 1024, /**< Allow dynamic changing of the
- * sampling rate during playback
- * with
- * pa_stream_update_sample_rate(). Only
- * supported when the server is at
- * least PA 0.9.8. It is ignored
- * on older servers. \since
- * 0.9.8 */
- PA_STREAM_PEAK_DETECT = 2048, /**< Find peaks instead of
- * resampling. \since 0.9.11 */
-
- PA_STREAM_START_MUTED = 4096, /**< Create in muted state. \since 0.9.11 */
-
- PA_STREAM_ADJUST_LATENCY = 8192, /**< Try to adjust the latency of
- * the sink/source based on the
- * requested buffer metrics and
- * adjust buffer metrics
- * accordingly. See pa_buffer_attr \since 0.9.11 */
+
+ PA_STREAM_START_CORKED = 0x0001U,
+ /**< Create the stream corked, requiring an explicit
+ * pa_stream_cork() call to uncork it. */
+
+ PA_STREAM_INTERPOLATE_TIMING = 0x0002U,
+ /**< Interpolate the latency for this stream. When enabled,
+ * pa_stream_get_latency() and pa_stream_get_time() will try to
+ * estimate the current record/playback time based on the local
+ * time that passed since the last timing info update. Using this
+ * option has the advantage of not requiring a whole roundtrip
+ * when the current playback/recording time is needed. Consider
+ * using this option when requesting latency information
+ * frequently. This is especially useful on long latency network
+ * connections. It makes a lot of sense to combine this option
+ * with PA_STREAM_AUTO_TIMING_UPDATE. */
+
+ PA_STREAM_NOT_MONOTONIC = 0x0004U,
+ /**< Don't force the time to increase monotonically. If this
+ * option is enabled, pa_stream_get_time() will not necessarily
+ * return always monotonically increasing time values on each
+ * call. This may confuse applications which cannot deal with time
+ * going 'backwards', but has the advantage that bad transport
+ * latency estimations that caused the time to to jump ahead can
+ * be corrected quickly, without the need to wait. (Please note
+ * that this flag was named PA_STREAM_NOT_MONOTONOUS in releases
+ * prior to 0.9.11. The old name is still defined too, for
+ * compatibility reasons. */
+
+ PA_STREAM_AUTO_TIMING_UPDATE = 0x0008U,
+ /**< If set timing update requests are issued periodically
+ * automatically. Combined with PA_STREAM_INTERPOLATE_TIMING you
+ * will be able to query the current time and latency with
+ * pa_stream_get_time() and pa_stream_get_latency() at all times
+ * without a packet round trip.*/
+
+ PA_STREAM_NO_REMAP_CHANNELS = 0x0010U,
+ /**< Don't remap channels by their name, instead map them simply
+ * by their index. Implies PA_STREAM_NO_REMIX_CHANNELS. Only
+ * supported when the server is at least PA 0.9.8. It is ignored
+ * on older servers.\since 0.9.8 */
+
+ PA_STREAM_NO_REMIX_CHANNELS = 0x0020U,
+ /**< When remapping channels by name, don't upmix or downmix them
+ * to related channels. Copy them into matching channels of the
+ * device 1:1. Only supported when the server is at least PA
+ * 0.9.8. It is ignored on older servers. \since 0.9.8 */
+
+ PA_STREAM_FIX_FORMAT = 0x0040U,
+ /**< Use the sample format of the sink/device this stream is being
+ * connected to, and possibly ignore the format the sample spec
+ * contains -- but you still have to pass a valid value in it as a
+ * hint to PulseAudio what would suit your stream best. If this is
+ * used you should query the used sample format after creating the
+ * stream by using pa_stream_get_sample_spec(). Also, if you
+ * specified manual buffer metrics it is recommended to update
+ * them with pa_stream_set_buffer_attr() to compensate for the
+ * changed frame sizes. Only supported when the server is at least
+ * PA 0.9.8. It is ignored on older servers. \since 0.9.8 */
+
+ PA_STREAM_FIX_RATE = 0x0080U,
+ /**< Use the sample rate of the sink, and possibly ignore the rate
+ * the sample spec contains. Usage similar to
+ * PA_STREAM_FIX_FORMAT.Only supported when the server is at least
+ * PA 0.9.8. It is ignored on older servers. \since 0.9.8 */
+
+ PA_STREAM_FIX_CHANNELS = 0x0100,
+ /**< Use the number of channels and the channel map of the sink,
+ * and possibly ignore the number of channels and the map the
+ * sample spec and the passed channel map contains. Usage similar
+ * to PA_STREAM_FIX_FORMAT. Only supported when the server is at
+ * least PA 0.9.8. It is ignored on older servers. \since 0.9.8 */
+
+ PA_STREAM_DONT_MOVE = 0x0200U,
+ /**< Don't allow moving of this stream to another
+ * sink/device. Useful if you use any of the PA_STREAM_FIX_ flags
+ * and want to make sure that resampling never takes place --
+ * which might happen if the stream is moved to another
+ * sink/source whith a different sample spec/channel map. Only
+ * supported when the server is at least PA 0.9.8. It is ignored
+ * on older servers. \since 0.9.8 */
+
+ PA_STREAM_VARIABLE_RATE = 0x0400U,
+ /**< Allow dynamic changing of the sampling rate during playback
+ * with pa_stream_update_sample_rate(). Only supported when the
+ * server is at least PA 0.9.8. It is ignored on older
+ * servers. \since 0.9.8 */
+
+ PA_STREAM_PEAK_DETECT = 0x0800U,
+ /**< Find peaks instead of resampling. \since 0.9.11 */
+
+ PA_STREAM_START_MUTED = 0x1000U,
+ /**< Create in muted state. If neither PA_STREAM_START_UNMUTED nor
+ * PA_STREAM_START_MUTED it is left to the server to decide
+ * whether to create the stream in muted or in unmuted
+ * state. \since 0.9.11 */
+
+ PA_STREAM_ADJUST_LATENCY = 0x2000U,
+ /**< Try to adjust the latency of the sink/source based on the
+ * requested buffer metrics and adjust buffer metrics
+ * accordingly. Also see pa_buffer_attr. This option may not be
+ * specified at the same time as PA_STREAM_EARLY_REQUESTS. \since
+ * 0.9.11 */
+
+ PA_STREAM_EARLY_REQUESTS = 0x4000U,
+ /**< Enable compatibility mode for legacy clients that rely on a
+ * "classic" hardware device fragment-style playback model. If
+ * this option is set, the minreq value of the buffer metrics gets
+ * a new meaning: instead of just specifying that no requests
+ * asking for less new data than this value will be made to the
+ * client it will also guarantee that requests are generated as
+ * early as this limit is reached. This flag should only be set in
+ * very few situations where compatiblity with a fragment-based
+ * playback model needs to be kept and the client applications
+ * cannot deal with data requests that are delayed to the latest
+ * moment possible. (Usually these are programs that use usleep()
+ * or a similar call in their playback loops instead of sleeping
+ * on the device itself.) Also see pa_buffer_attr. This option may
+ * not be specified at the same time as
+ * PA_STREAM_ADJUST_LATENCY. \since 0.9.12 */
+
+ PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND = 0x8000U,
+ /**< If set this stream won't be taken into account when we it is
+ * checked whether the device this stream is connected to should
+ * auto-suspend. \ since 0.9.14 */
+
+ PA_STREAM_START_UNMUTED = 0x10000U
+ /**< Create in unmuted state. If neither PA_STREAM_START_UNMUTED
+ * nor PA_STREAM_START_MUTED it is left to the server to decide
+ * whether to create the stream in muted or in unmuted
+ * state. \since 0.9.14 */
+
} pa_stream_flags_t;
+/** \cond fulldocs */
-/** English is an evil language */
+/* English is an evil language */
#define PA_STREAM_NOT_MONOTONOUS PA_STREAM_NOT_MONOTONIC
+/* Allow clients to check with #ifdef for those flags */
+#define PA_STREAM_START_CORKED PA_STREAM_START_CORKED
+#define PA_STREAM_INTERPOLATE_TIMING PA_STREAM_INTERPOLATE_TIMING
+#define PA_STREAM_NOT_MONOTONIC PA_STREAM_NOT_MONOTONIC
+#define PA_STREAM_AUTO_TIMING_UPDATE PA_STREAM_AUTO_TIMING_UPDATE
+#define PA_STREAM_NO_REMAP_CHANNELS PA_STREAM_NO_REMAP_CHANNELS
+#define PA_STREAM_NO_REMIX_CHANNELS PA_STREAM_NO_REMIX_CHANNELS
+#define PA_STREAM_FIX_FORMAT PA_STREAM_FIX_FORMAT
+#define PA_STREAM_FIX_RATE PA_STREAM_FIX_RATE
+#define PA_STREAM_FIX_CHANNELS PA_STREAM_FIX_CHANNELS
+#define PA_STREAM_DONT_MOVE PA_STREAM_DONT_MOVE
+#define PA_STREAM_VARIABLE_RATE PA_STREAM_VARIABLE_RATE
+#define PA_STREAM_PEAK_DETECT PA_STREAM_PEAK_DETECT
+#define PA_STREAM_START_MUTED PA_STREAM_START_MUTED
+#define PA_STREAM_ADJUST_LATENCY PA_STREAM_ADJUST_LATENCY
+#define PA_STREAM_EARLY_REQUESTS PA_STREAM_EARLY_REQUESTS
+#define PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND
+#define PA_STREAM_START_UNMUTED PA_STREAM_START_UNMUTED
+
+/** \endcond */
+
/** Playback and record buffer metrics */
typedef struct pa_buffer_attr {
- uint32_t maxlength; /**< Maximum length of the
- * buffer. Setting this to (uint32_t) -1 will
- * initialize this to the maximum value
- * supported by server, which is
- * recommended. */
- uint32_t tlength; /**< Playback only: target length of the
- * buffer. The server tries to assure
- * that at least tlength bytes are always
- * available in the per-stream
- * server-side playback buffer. It is
- * recommended to set this to (uint32_t)
- * -1, which will initialize this to a
- * value that is deemed sensible by the
- * server. However, this value will
- * default to something like 2s, i.e. for
- * applications that have specific
- * latency requirements this value should
- * be set to the maximum latency that the
- * application can deal with. When
- * PA_STREAM_ADJUST_LATENCY is not set
- * this value will influence only the
- * per-stream playback buffer size. When
- * PA_STREAM_ADJUST_LATENCY is set the
- * overall latency of the sink plus the
- * playback buffer size is configured to
- * this value. Set
- * PA_STREAM_ADJUST_LATENCY if you are
- * interested in adjusting the overall
- * latency. Don't set it if you are
- * interested in configuring the
- * server-sider per-stream playback
- * buffer size. */
- uint32_t prebuf; /**< Playback only: pre-buffering. The
- * server does not start with playback
- * before at least prebug bytes are
- * available in the buffer. It is
- * recommended to set this to (uint32_t)
- * -1, which will initialize this to the
- * same value as tlength, whatever that
- * may be. Initialize to 0 to enable
- * manual start/stop control of the
- * stream. This means that playback will
- * not stop on underrun and playback will
- * not start automatically. Instead
- * pa_stream_corked() needs to be called
- * explicitly. If you set this value to 0
- * you should also set
- * PA_STREAM_START_CORKED. */
- uint32_t minreq; /**< Playback only: minimum request. The
- * server does not request less than
- * minreq bytes from the client, instead
- * waits until the buffer is free enough
- * to request more bytes at once. It is
- * recommended to set this to (uint32_t)
- * -1, which will initialize this to a
- * value that is deemed sensible by the
- * server. This should be set to a value
- * that gives PulseAudio enough time to
- * move the data from the per-stream
- * playback buffer into the hardware
- * playback buffer. */
- uint32_t fragsize; /**< Recording only: fragment size. The
- * server sends data in blocks of
- * fragsize bytes size. Large values
- * deminish interactivity with other
- * operations on the connection context
- * but decrease control overhead. It is
- * recommended to set this to (uint32_t)
- * -1, which will initialize this to a
- * value that is deemed sensible by the
- * server. However, this value will
- * default to something like 2s, i.e. for
- * applications that have specific
- * latency requirements this value should
- * be set to the maximum latency that the
- * application can deal with. If
- * PA_STREAM_ADJUST_LATENCY is set the
- * overall source latency will be
- * adjusted according to this value. If
- * it is not set the source latency is
- * left unmodified. */
+ uint32_t maxlength;
+ /**< Maximum length of the buffer. Setting this to (uint32_t) -1
+ * will initialize this to the maximum value supported by server,
+ * which is recommended. */
+
+ uint32_t tlength;
+ /**< Playback only: target length of the buffer. The server tries
+ * to assure that at least tlength bytes are always available in
+ * the per-stream server-side playback buffer. It is recommended
+ * to set this to (uint32_t) -1, which will initialize this to a
+ * value that is deemed sensible by the server. However, this
+ * value will default to something like 2s, i.e. for applications
+ * that have specific latency requirements this value should be
+ * set to the maximum latency that the application can deal
+ * with. When PA_STREAM_ADJUST_LATENCY is not set this value will
+ * influence only the per-stream playback buffer size. When
+ * PA_STREAM_ADJUST_LATENCY is set the overall latency of the sink
+ * plus the playback buffer size is configured to this value. Set
+ * PA_STREAM_ADJUST_LATENCY if you are interested in adjusting the
+ * overall latency. Don't set it if you are interested in
+ * configuring the server-sider per-stream playback buffer
+ * size. */
+
+ uint32_t prebuf;
+ /**< Playback only: pre-buffering. The server does not start with
+ * playback before at least prebug bytes are available in the
+ * buffer. It is recommended to set this to (uint32_t) -1, which
+ * will initialize this to the same value as tlength, whatever
+ * that may be. Initialize to 0 to enable manual start/stop
+ * control of the stream. This means that playback will not stop
+ * on underrun and playback will not start automatically. Instead
+ * pa_stream_corked() needs to be called explicitly. If you set
+ * this value to 0 you should also set PA_STREAM_START_CORKED. */
+
+ uint32_t minreq;
+ /**< Playback only: minimum request. The server does not request
+ * less than minreq bytes from the client, instead waits until the
+ * buffer is free enough to request more bytes at once. It is
+ * recommended to set this to (uint32_t) -1, which will initialize
+ * this to a value that is deemed sensible by the server. This
+ * should be set to a value that gives PulseAudio enough time to
+ * move the data from the per-stream playback buffer into the
+ * hardware playback buffer. */
+
+ uint32_t fragsize;
+ /**< Recording only: fragment size. The server sends data in
+ * blocks of fragsize bytes size. Large values deminish
+ * interactivity with other operations on the connection context
+ * but decrease control overhead. It is recommended to set this to
+ * (uint32_t) -1, which will initialize this to a value that is
+ * deemed sensible by the server. However, this value will default
+ * to something like 2s, i.e. for applications that have specific
+ * latency requirements this value should be set to the maximum
+ * latency that the application can deal with. If
+ * PA_STREAM_ADJUST_LATENCY is set the overall source latency will
+ * be adjusted according to this value. If it is not set the
+ * source latency is left unmodified. */
+
} pa_buffer_attr;
/** Error values as used by pa_context_errno(). Use pa_strerror() to convert these values to human readable strings */
@@ -358,36 +353,84 @@ enum {
/** Subscription event mask, as used by pa_context_subscribe() */
typedef enum pa_subscription_mask {
- PA_SUBSCRIPTION_MASK_NULL = 0, /**< No events */
- PA_SUBSCRIPTION_MASK_SINK = 1, /**< Sink events */
- PA_SUBSCRIPTION_MASK_SOURCE = 2, /**< Source events */
- PA_SUBSCRIPTION_MASK_SINK_INPUT = 4, /**< Sink input events */
- PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 8, /**< Source output events */
- PA_SUBSCRIPTION_MASK_MODULE = 16, /**< Module events */
- PA_SUBSCRIPTION_MASK_CLIENT = 32, /**< Client events */
- PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 64, /**< Sample cache events */
- PA_SUBSCRIPTION_MASK_SERVER = 128, /**< Other global server changes. */
- PA_SUBSCRIPTION_MASK_AUTOLOAD = 256, /**< Autoload table events. */
- PA_SUBSCRIPTION_MASK_ALL = 511 /**< Catch all events */
+ PA_SUBSCRIPTION_MASK_NULL = 0x0000U,
+ /**< No events */
+
+ PA_SUBSCRIPTION_MASK_SINK = 0x0001U,
+ /**< Sink events */
+
+ PA_SUBSCRIPTION_MASK_SOURCE = 0x0002U,
+ /**< Source events */
+
+ PA_SUBSCRIPTION_MASK_SINK_INPUT = 0x0004U,
+ /**< Sink input events */
+
+ PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 0x0008U,
+ /**< Source output events */
+
+ PA_SUBSCRIPTION_MASK_MODULE = 0x0010U,
+ /**< Module events */
+
+ PA_SUBSCRIPTION_MASK_CLIENT = 0x0020U,
+ /**< Client events */
+
+ PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 0x0040U,
+ /**< Sample cache events */
+
+ PA_SUBSCRIPTION_MASK_SERVER = 0x0080U,
+ /**< Other global server changes. */
+
+ PA_SUBSCRIPTION_MASK_AUTOLOAD = 0x0100U,
+ /**< Autoload table events. */
+
+ PA_SUBSCRIPTION_MASK_ALL = 0x01ffU
+ /**< Catch all events */
} pa_subscription_mask_t;
/** Subscription event types, as used by pa_context_subscribe() */
typedef enum pa_subscription_event_type {
- PA_SUBSCRIPTION_EVENT_SINK = 0, /**< Event type: Sink */
- PA_SUBSCRIPTION_EVENT_SOURCE = 1, /**< Event type: Source */
- PA_SUBSCRIPTION_EVENT_SINK_INPUT = 2, /**< Event type: Sink input */
- PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 3, /**< Event type: Source output */
- PA_SUBSCRIPTION_EVENT_MODULE = 4, /**< Event type: Module */
- PA_SUBSCRIPTION_EVENT_CLIENT = 5, /**< Event type: Client */
- PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 6, /**< Event type: Sample cache item */
- PA_SUBSCRIPTION_EVENT_SERVER = 7, /**< Event type: Global server change, only occuring with PA_SUBSCRIPTION_EVENT_CHANGE. */
- PA_SUBSCRIPTION_EVENT_AUTOLOAD = 8, /**< Event type: Autoload table changes. */
- PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 15, /**< A mask to extract the event type from an event value */
-
- PA_SUBSCRIPTION_EVENT_NEW = 0, /**< A new object was created */
- PA_SUBSCRIPTION_EVENT_CHANGE = 16, /**< A property of the object was modified */
- PA_SUBSCRIPTION_EVENT_REMOVE = 32, /**< An object was removed */
- PA_SUBSCRIPTION_EVENT_TYPE_MASK = 16+32 /**< A mask to extract the event operation from an event value */
+ PA_SUBSCRIPTION_EVENT_SINK = 0x0000U,
+ /**< Event type: Sink */
+
+ PA_SUBSCRIPTION_EVENT_SOURCE = 0x0001U,
+ /**< Event type: Source */
+
+ PA_SUBSCRIPTION_EVENT_SINK_INPUT = 0x0002U,
+ /**< Event type: Sink input */
+
+ PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 0x0003U,
+ /**< Event type: Source output */
+
+ PA_SUBSCRIPTION_EVENT_MODULE = 0x0004U,
+ /**< Event type: Module */
+
+ PA_SUBSCRIPTION_EVENT_CLIENT = 0x0005U,
+ /**< Event type: Client */
+
+ PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 0x0006U,
+ /**< Event type: Sample cache item */
+
+ PA_SUBSCRIPTION_EVENT_SERVER = 0x0007U,
+ /**< Event type: Global server change, only occuring with PA_SUBSCRIPTION_EVENT_CHANGE. */
+
+ PA_SUBSCRIPTION_EVENT_AUTOLOAD = 0x0008U,
+ /**< Event type: Autoload table changes. */
+
+ PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 0x000FU,
+ /**< A mask to extract the event type from an event value */
+
+ PA_SUBSCRIPTION_EVENT_NEW = 0x0000U,
+ /**< A new object was created */
+
+ PA_SUBSCRIPTION_EVENT_CHANGE = 0x0010U,
+ /**< A property of the object was modified */
+
+ PA_SUBSCRIPTION_EVENT_REMOVE = 0x0020U,
+ /**< An object was removed */
+
+ PA_SUBSCRIPTION_EVENT_TYPE_MASK = 0x0030U,
+ /**< A mask to extract the event operation from an event value */
+
} pa_subscription_event_type_t;
/** Return one if an event type t matches an event mask bitfield */
@@ -412,69 +455,71 @@ typedef enum pa_subscription_event_type {
* note that this structure can be extended as part of evolutionary
* API updates at any time in any new release.*/
typedef struct pa_timing_info {
- struct timeval timestamp; /**< The time when this timing info structure was current */
- int synchronized_clocks; /**< Non-zero if the local and the
- * remote machine have synchronized
- * clocks. If synchronized clocks are
- * detected transport_usec becomes much
- * more reliable. However, the code that
- * detects synchronized clocks is very
- * limited und unreliable itself. */
-
- pa_usec_t sink_usec; /**< Time in usecs a sample takes to be played on the sink. For playback streams and record streams connected to a monitor source. */
- pa_usec_t source_usec; /**< Time in usecs a sample takes from being recorded to being delivered to the application. Only for record streams. */
- pa_usec_t transport_usec; /**< Estimated time in usecs a sample takes to be transferred to/from the daemon. For both playback and record streams. */
-
- int playing; /**< Non-zero when the stream is
- * currently not underrun and data is
- * being passed on to the device. Only
- * for playback streams. This field does
- * not say whether the data is actually
- * already being played. To determine
- * this check whether since_underrun
- * (converted to usec) is larger than
- * sink_usec.*/
-
- int write_index_corrupt; /**< Non-zero if write_index is not
- * up-to-date because a local write
- * command that corrupted it has been
- * issued in the time since this latency
- * info was current . Only write
- * commands with SEEK_RELATIVE_ON_READ
- * and SEEK_RELATIVE_END can corrupt
- * write_index. */
- int64_t write_index; /**< Current write index into the
- * playback buffer in bytes. Think twice before
- * using this for seeking purposes: it
- * might be out of date a the time you
- * want to use it. Consider using
- * PA_SEEK_RELATIVE instead. */
-
- int read_index_corrupt; /**< Non-zero if read_index is not
- * up-to-date because a local pause or
- * flush request that corrupted it has
- * been issued in the time since this
- * latency info was current. */
-
- int64_t read_index; /**< Current read index into the
- * playback buffer in bytes. Think twice before
- * using this for seeking purposes: it
- * might be out of date a the time you
- * want to use it. Consider using
- * PA_SEEK_RELATIVE_ON_READ
- * instead. */
-
- pa_usec_t configured_sink_usec; /**< The configured latency for
- * the sink. \since 0.9.11 */
- pa_usec_t configured_source_usec; /**< The configured latency for
- * the source. \since 0.9.11 */
-
- int64_t since_underrun; /**< Bytes that were handed to the sink
- since the last underrun happened, or
- since playback started again after
- the last underrun. playing will tell
- you which case it is. \since
- 0.9.11 */
+ struct timeval timestamp;
+ /**< The time when this timing info structure was current */
+
+ int synchronized_clocks;
+ /**< Non-zero if the local and the remote machine have
+ * synchronized clocks. If synchronized clocks are detected
+ * transport_usec becomes much more reliable. However, the code
+ * that detects synchronized clocks is very limited und unreliable
+ * itself. */
+
+ pa_usec_t sink_usec;
+ /**< Time in usecs a sample takes to be played on the sink. For
+ * playback streams and record streams connected to a monitor
+ * source. */
+
+ pa_usec_t source_usec;
+ /**< Time in usecs a sample takes from being recorded to being
+ * delivered to the application. Only for record streams. */
+
+ pa_usec_t transport_usec;
+ /**< Estimated time in usecs a sample takes to be transferred
+ * to/from the daemon. For both playback and record streams. */
+
+ int playing;
+ /**< Non-zero when the stream is currently not underrun and data
+ * is being passed on to the device. Only for playback
+ * streams. This field does not say whether the data is actually
+ * already being played. To determine this check whether
+ * since_underrun (converted to usec) is larger than sink_usec.*/
+
+ int write_index_corrupt;
+ /**< Non-zero if write_index is not up-to-date because a local
+ * write command that corrupted it has been issued in the time
+ * since this latency info was current . Only write commands with
+ * SEEK_RELATIVE_ON_READ and SEEK_RELATIVE_END can corrupt
+ * write_index. */
+
+ int64_t write_index;
+ /**< Current write index into the playback buffer in bytes. Think
+ * twice before using this for seeking purposes: it might be out
+ * of date a the time you want to use it. Consider using
+ * PA_SEEK_RELATIVE instead. */
+
+ int read_index_corrupt;
+ /**< Non-zero if read_index is not up-to-date because a local
+ * pause or flush request that corrupted it has been issued in the
+ * time since this latency info was current. */
+
+ int64_t read_index;
+ /**< Current read index into the playback buffer in bytes. Think
+ * twice before using this for seeking purposes: it might be out
+ * of date a the time you want to use it. Consider using
+ * PA_SEEK_RELATIVE_ON_READ instead. */
+
+ pa_usec_t configured_sink_usec;
+ /**< The configured latency for the sink. \since 0.9.11 */
+
+ pa_usec_t configured_source_usec;
+ /**< The configured latency for * the source. \since 0.9.11 */
+
+ int64_t since_underrun;
+ /**< Bytes that were handed to the sink since the last underrun
+ * happened, or since playback started again after the last
+ * underrun. playing will tell you which case it is. \since
+ * 0.9.11 */
} pa_timing_info;
@@ -486,45 +531,101 @@ typedef struct pa_timing_info {
* thread compatible way. You might have to do this in
* prefork/postfork. */
typedef struct pa_spawn_api {
- void (*prefork)(void); /**< Is called just before the fork in the parent process. May be NULL. */
- void (*postfork)(void); /**< Is called immediately after the fork in the parent process. May be NULL.*/
- void (*atfork)(void); /**< Is called immediately after the
- * fork in the child process. May be
- * NULL. It is not safe to close all
- * file descriptors in this function
- * unconditionally, since a UNIX socket
- * (created using socketpair()) is
- * passed to the new process. */
+ void (*prefork)(void);
+ /**< Is called just before the fork in the parent process. May be
+ * NULL. */
+
+ void (*postfork)(void);
+ /**< Is called immediately after the fork in the parent
+ * process. May be NULL.*/
+
+ void (*atfork)(void);
+ /**< Is called immediately after the fork in the child
+ * process. May be NULL. It is not safe to close all file
+ * descriptors in this function unconditionally, since a UNIX
+ * socket (created using socketpair()) is passed to the new
+ * process. */
} pa_spawn_api;
/** Seek type for pa_stream_write(). */
typedef enum pa_seek_mode {
- PA_SEEK_RELATIVE = 0, /**< Seek relatively to the write index */
- PA_SEEK_ABSOLUTE = 1, /**< Seek relatively to the start of the buffer queue */
- PA_SEEK_RELATIVE_ON_READ = 2, /**< Seek relatively to the read index. */
- PA_SEEK_RELATIVE_END = 3 /**< Seek relatively to the current end of the buffer queue. */
+ PA_SEEK_RELATIVE = 0,
+ /**< Seek relatively to the write index */
+
+ PA_SEEK_ABSOLUTE = 1,
+ /**< Seek relatively to the start of the buffer queue */
+
+ PA_SEEK_RELATIVE_ON_READ = 2,
+ /**< Seek relatively to the read index. */
+
+ PA_SEEK_RELATIVE_END = 3
+ /**< Seek relatively to the current end of the buffer queue. */
} pa_seek_mode_t;
/** Special sink flags. */
typedef enum pa_sink_flags {
- PA_SINK_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */
- PA_SINK_LATENCY = 2, /**< Supports latency querying */
- PA_SINK_HARDWARE = 4, /**< Is a hardware sink of some kind, in contrast to "virtual"/software sinks \since 0.9.3 */
- PA_SINK_NETWORK = 8, /**< Is a networked sink of some kind. \since 0.9.7 */
- PA_SINK_HW_MUTE_CTRL = 16, /**< Supports hardware mute control \since 0.9.11 */
- PA_SINK_DECIBEL_VOLUME = 32 /**< Volume can be translated to dB with pa_sw_volume_to_dB() \since 0.9.11 */
+ PA_SINK_HW_VOLUME_CTRL = 0x0001U,
+ /**< Supports hardware volume control */
+
+ PA_SINK_LATENCY = 0x0002U,
+ /**< Supports latency querying */
+
+ PA_SINK_HARDWARE = 0x0004U,
+ /**< Is a hardware sink of some kind, in contrast to
+ * "virtual"/software sinks \since 0.9.3 */
+
+ PA_SINK_NETWORK = 0x0008U,
+ /**< Is a networked sink of some kind. \since 0.9.7 */
+
+ PA_SINK_HW_MUTE_CTRL = 0x0010U,
+ /**< Supports hardware mute control \since 0.9.11 */
+
+ PA_SINK_DECIBEL_VOLUME = 0x0020U
+ /**< Volume can be translated to dB with pa_sw_volume_to_dB()
+ * \since 0.9.11 */
} pa_sink_flags_t;
+/** \cond fulldocs */
+#define PA_SINK_HW_VOLUME_CTRL PA_SINK_HW_VOLUME_CTRL
+#define PA_SINK_LATENCY PA_SINK_LATENCY
+#define PA_SINK_HARDWARE PA_SINK_HARDWARE
+#define PA_SINK_NETWORK PA_SINK_NETWORK
+#define PA_SINK_HW_VOLUME_CTRL PA_SINK_HW_VOLUME_CTRL
+#define PA_SINK_DECIBEL_VOLUME PA_SINK_DECIBEL_VOLUME
+/** \endcond */
+
/** Special source flags. */
typedef enum pa_source_flags {
- PA_SOURCE_HW_VOLUME_CTRL = 1, /**< Supports hardware volume control */
- PA_SOURCE_LATENCY = 2, /**< Supports latency querying */
- PA_SOURCE_HARDWARE = 4, /**< Is a hardware source of some kind, in contrast to "virtual"/software source \since 0.9.3 */
- PA_SOURCE_NETWORK = 8, /**< Is a networked sink of some kind. \since 0.9.7 */
- PA_SOURCE_HW_MUTE_CTRL = 16, /**< Supports hardware mute control \since 0.9.11 */
- PA_SOURCE_DECIBEL_VOLUME = 32 /**< Volume can be translated to dB with pa_sw_volume_to_dB() \since 0.9.11 */
+ PA_SOURCE_HW_VOLUME_CTRL = 0x0001U,
+ /**< Supports hardware volume control */
+
+ PA_SOURCE_LATENCY = 0x0002U,
+ /**< Supports latency querying */
+
+ PA_SOURCE_HARDWARE = 0x0004U,
+ /**< Is a hardware source of some kind, in contrast to
+ * "virtual"/software source \since 0.9.3 */
+
+ PA_SOURCE_NETWORK = 0x0008U,
+ /**< Is a networked sink of some kind. \since 0.9.7 */
+
+ PA_SOURCE_HW_MUTE_CTRL = 0x0010U,
+ /**< Supports hardware mute control \since 0.9.11 */
+
+ PA_SOURCE_DECIBEL_VOLUME = 0x0020U
+ /**< Volume can be translated to dB with pa_sw_volume_to_dB()
+ * \since 0.9.11 */
} pa_source_flags_t;
+/** \cond fulldocs */
+#define PA_SOURCE_HW_VOLUME_CTRL PA_SOURCE_HW_VOLUME_CTRL
+#define PA_SOURCE_LATENCY PA_SOURCE_LATENCY
+#define PA_SOURCE_HARDWARE PA_SOURCE_HARDWARE
+#define PA_SOURCE_NETWORK PA_SOURCE_NETWORK
+#define PA_SOURCE_HW_VOLUME_CTRL PA_SOURCE_HW_VOLUME_CTRL
+#define PA_SOURCE_DECIBEL_VOLUME PA_SOURCE_DECIBEL_VOLUME
+/** \endcond */
+
/** A generic free() like callback prototype */
typedef void (*pa_free_cb_t)(void *p);
diff --git a/src/pulse/ext-stream-restore.h b/src/pulse/ext-stream-restore.h
index a8eceaf1..2038eb4a 100644
--- a/src/pulse/ext-stream-restore.h
+++ b/src/pulse/ext-stream-restore.h
@@ -24,37 +24,49 @@
#include <pulse/context.h>
+/** \file
+ *
+ * Routines for controlling module-stream-restore
+ */
+
PA_C_DECL_BEGIN
+/** Stores information about one entry in the stream database that is
+ * maintained by module-stream-restore. \since 0.9.12 */
typedef struct pa_ext_stream_restore_info {
- const char *name;
- pa_channel_map channel_map;
- pa_cvolume volume;
- const char *device;
- int mute;
+ const char *name; /**< Identifier string of the stream. A string like "sink-input-by-role:" or similar followed by some arbitrary property value. */
+ pa_channel_map channel_map; /**< The channel map for the volume field */
+ pa_cvolume volume; /**< The volume of the stream when it was seen last, if applicable */
+ const char *device; /**< The sink/source of the stream when it was last seen */
+ int mute; /**< The boolean mute state of the stream when it was last seen, if applicable */
} pa_ext_stream_restore_info;
+/** Callback prototype for pa_ext_stream_restore_test(). \since 0.9.12 */
typedef void (*pa_ext_stream_restore_test_cb_t)(
pa_context *c,
uint32_t version,
void *userdata);
+/** Test if this extension module is available in the server. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_test(
pa_context *c,
pa_ext_stream_restore_test_cb_t cb,
void *userdata);
+/** Callback prototype for pa_ext_stream_restore_read(). \since 0.9.12 */
typedef void (*pa_ext_stream_restore_read_cb_t)(
pa_context *c,
const pa_ext_stream_restore_info *info,
int eol,
void *userdata);
+/** Read all entries from the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_read(
pa_context *c,
pa_ext_stream_restore_read_cb_t cb,
void *userdata);
+/** Store entries in the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_write(
pa_context *c,
pa_update_mode_t mode,
@@ -64,22 +76,27 @@ pa_operation *pa_ext_stream_restore_write(
pa_context_success_cb_t cb,
void *userdata);
+/** Delete entries from the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_delete(
pa_context *c,
const char *const s[],
pa_context_success_cb_t cb,
void *userdata);
+/** Subscribe to changes in the stream database. \since 0.9.12 */
pa_operation *pa_ext_stream_restore_subscribe(
pa_context *c,
int enable,
pa_context_success_cb_t cb,
void *userdata);
+/** Callback prototype for pa_ext_stream_restore_set_subscribe_cb(). \since 0.9.12 */
typedef void (*pa_ext_stream_restore_subscribe_cb_t)(
pa_context *c,
void *userdata);
+/** Set the subscription callback that is called when
+ * pa_ext_stream_restore_subscribe() was called. \since 0.9.12 */
void pa_ext_stream_restore_set_subscribe_cb(
pa_context *c,
pa_ext_stream_restore_subscribe_cb_t cb,
diff --git a/src/pulse/gccmacro.h b/src/pulse/gccmacro.h
index e4062033..0533b109 100644
--- a/src/pulse/gccmacro.h
+++ b/src/pulse/gccmacro.h
@@ -93,4 +93,24 @@
#endif
#endif
+#ifndef PA_GCC_ALLOC_SIZE
+#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 3)
+#define PA_GCC_ALLOC_SIZE(x) __attribute__ ((__alloc_size__(x)))
+#define PA_GCC_ALLOC_SIZE2(x,y) __attribute__ ((__alloc_size__(x,y)))
+#else
+/** Macro for usage of GCC's alloc_size attribute */
+#define PA_GCC_ALLOC_SIZE(x)
+#define PA_GCC_ALLOC_SIZE2(x,y)
+#endif
+#endif
+
+#ifndef PA_GCC_MALLOC
+#ifdef __GNUCC__
+#define PA_GCC_MALLOC __attribute__ ((malloc))
+#else
+/** Macro for usage of GCC's malloc attribute */
+#define PA_GCC_MALLOC
+#endif
+#endif
+
#endif
diff --git a/src/pulse/glib-mainloop.c b/src/pulse/glib-mainloop.c
index 6ddb0faa..5f5dc494 100644
--- a/src/pulse/glib-mainloop.c
+++ b/src/pulse/glib-mainloop.c
@@ -195,11 +195,11 @@ static void cleanup_defer_events(pa_glib_mainloop *g, int force) {
}
static gushort map_flags_to_glib(pa_io_event_flags_t flags) {
- return
- (flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) |
- (flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) |
- (flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) |
- (flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0);
+ return (gushort)
+ ((flags & PA_IO_EVENT_INPUT ? G_IO_IN : 0) |
+ (flags & PA_IO_EVENT_OUTPUT ? G_IO_OUT : 0) |
+ (flags & PA_IO_EVENT_ERROR ? G_IO_ERR : 0) |
+ (flags & PA_IO_EVENT_HANGUP ? G_IO_HUP : 0));
}
static pa_io_event_flags_t map_flags_from_glib(gushort flags) {
@@ -425,7 +425,7 @@ static void glib_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_
/* quit() */
-static void glib_quit(pa_mainloop_api*a, PA_GCC_UNUSED int retval) {
+static void glib_quit(pa_mainloop_api*a, int retval) {
g_warning("quit() ignored");
@@ -536,7 +536,7 @@ static gboolean check_func(GSource *source) {
return FALSE;
}
-static gboolean dispatch_func(GSource *source, PA_GCC_UNUSED GSourceFunc callback, PA_GCC_UNUSED gpointer userdata) {
+static gboolean dispatch_func(GSource *source, GSourceFunc callback, gpointer userdata) {
pa_glib_mainloop *g = (pa_glib_mainloop*) source;
pa_io_event *e;
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index bfe888ee..5fe4210e 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -64,7 +64,7 @@ struct pa_context {
uint32_t version;
uint32_t ctag;
uint32_t csyncid;
- uint32_t error;
+ int error;
pa_context_state_t state;
pa_context_notify_cb_t state_callback;
@@ -75,9 +75,9 @@ struct pa_context {
pa_mempool *mempool;
pa_bool_t is_local:1;
- pa_bool_t do_autospawn:1;
pa_bool_t do_shm:1;
- int autospawn_lock_fd;
+
+ pa_bool_t do_autospawn:1;
pa_spawn_api spawn_api;
pa_strlist *server_list;
diff --git a/src/pulse/introspect.c b/src/pulse/introspect.c
index 4be2c62a..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>
@@ -36,7 +38,7 @@
/*** Statistics ***/
-static void context_stat_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_stat_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
pa_stat_info i, *p = &i;
@@ -79,7 +81,7 @@ pa_operation* pa_context_stat(pa_context *c, pa_stat_info_cb_t cb, void *userdat
/*** Server Info ***/
-static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_server_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
pa_server_info i, *p = &i;
@@ -127,7 +129,7 @@ pa_operation* pa_context_get_server_info(pa_context *c, pa_server_info_cb_t cb,
/*** Sink Info ***/
-static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_sink_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -248,7 +250,7 @@ pa_operation* pa_context_get_sink_info_by_name(pa_context *c, const char *name,
/*** Source info ***/
-static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_source_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -369,7 +371,7 @@ pa_operation* pa_context_get_source_info_by_name(pa_context *c, const char *name
/*** Client info ***/
-static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_client_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -451,7 +453,7 @@ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t
/*** Module info ***/
-static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_module_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -530,7 +532,7 @@ pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t
/*** Sink input info ***/
-static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_sink_input_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -624,7 +626,7 @@ pa_operation* pa_context_get_sink_input_info_list(pa_context *c, void (*cb)(pa_c
/*** Source output info ***/
-static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_source_output_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -954,7 +956,7 @@ pa_operation* pa_context_set_source_mute_by_name(pa_context *c, const char *name
/** Sample Cache **/
-static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_sample_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
@@ -1098,7 +1100,7 @@ pa_operation* pa_context_kill_source_output(pa_context *c, uint32_t idx, pa_cont
return command_kill(c, PA_COMMAND_KILL_SOURCE_OUTPUT, idx, cb, userdata);
}
-static void context_index_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_index_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
uint32_t idx;
@@ -1159,7 +1161,7 @@ pa_operation* pa_context_unload_module(pa_context *c, uint32_t idx, pa_context_s
/*** Autoload stuff ***/
-static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void context_get_autoload_info_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int eol = 1;
diff --git a/src/pulse/introspect.h b/src/pulse/introspect.h
index ca79f5b7..087bd9f9 100644
--- a/src/pulse/introspect.h
+++ b/src/pulse/introspect.h
@@ -561,7 +561,7 @@ typedef enum pa_autoload_type {
typedef struct pa_autoload_info {
uint32_t index; /**< Index of this autoload entry */
const char *name; /**< Name of the sink or source */
- pa_autoload_type_t type; /**< Type of the autoload entry */
+ pa_autoload_type_t type; /**< Type of the autoload entry */
const char *module; /**< Module name to load */
const char *argument; /**< Argument string for module */
} pa_autoload_info;
diff --git a/src/pulse/mainloop-api.c b/src/pulse/mainloop-api.c
index 4e3b135a..4b862f9a 100644
--- a/src/pulse/mainloop-api.c
+++ b/src/pulse/mainloop-api.c
@@ -51,7 +51,7 @@ static void once_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata)
m->defer_free(e);
}
-static void free_callback(pa_mainloop_api *m, PA_GCC_UNUSED pa_defer_event *e, void *userdata) {
+static void free_callback(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
struct once_info *i = userdata;
pa_assert(m);
diff --git a/src/pulse/mainloop-signal.c b/src/pulse/mainloop-signal.c
index e95968ae..d09f4b0a 100644
--- a/src/pulse/mainloop-signal.c
+++ b/src/pulse/mainloop-signal.c
@@ -90,7 +90,7 @@ static void dispatch(pa_mainloop_api*a, int sig) {
}
}
-static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, PA_GCC_UNUSED void *userdata) {
+static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, void *userdata) {
ssize_t r;
int sig;
diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c
index 5823e280..60e5d1ff 100644
--- a/src/pulse/mainloop.c
+++ b/src/pulse/mainloop.c
@@ -57,7 +57,7 @@
struct pa_io_event {
pa_mainloop *mainloop;
- int dead;
+ pa_bool_t dead:1;
int fd;
pa_io_event_flags_t events;
@@ -72,9 +72,9 @@ struct pa_io_event {
struct pa_time_event {
pa_mainloop *mainloop;
- int dead;
+ pa_bool_t dead:1;
- int enabled;
+ pa_bool_t enabled:1;
struct timeval timeval;
pa_time_event_cb_t callback;
@@ -86,9 +86,9 @@ struct pa_time_event {
struct pa_defer_event {
pa_mainloop *mainloop;
- int dead;
+ pa_bool_t dead:1;
- int enabled;
+ pa_bool_t enabled:1;
pa_defer_event_cb_t callback;
void *userdata;
@@ -102,22 +102,24 @@ struct pa_mainloop {
PA_LLIST_HEAD(pa_time_event, time_events);
PA_LLIST_HEAD(pa_defer_event, defer_events);
- int n_enabled_defer_events, n_enabled_time_events, n_io_events;
- int io_events_please_scan, time_events_please_scan, defer_events_please_scan;
+ unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
+ unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
+ pa_bool_t rebuild_pollfds:1;
struct pollfd *pollfds;
unsigned max_pollfds, n_pollfds;
- int rebuild_pollfds;
int prepared_timeout;
pa_time_event *cached_next_time_event;
- int quit, retval;
pa_mainloop_api api;
+ int retval;
+ pa_bool_t quit:1;
+
+ pa_bool_t wakeup_requested:1;
int wakeup_pipe[2];
int wakeup_pipe_type;
- int wakeup_requested;
enum {
STATE_PASSIVE,
@@ -133,11 +135,11 @@ struct pa_mainloop {
};
static short map_flags_to_libc(pa_io_event_flags_t flags) {
- return
- (flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
- (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
- (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
- (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0);
+ return (short)
+ ((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
+ (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
+ (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
+ (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0));
}
static pa_io_event_flags_t map_flags_from_libc(short flags) {
@@ -169,7 +171,7 @@ static pa_io_event* mainloop_io_new(
e = pa_xnew(pa_io_event, 1);
e->mainloop = m;
- e->dead = 0;
+ e->dead = FALSE;
e->fd = fd;
e->events = events;
@@ -194,13 +196,13 @@ static pa_io_event* mainloop_io_new(
SELECT_TYPE_ARG5 &tv) == -1) &&
(WSAGetLastError() == WSAENOTSOCK)) {
pa_log_warn("Cannot monitor non-socket file descriptors.");
- e->dead = 1;
+ e->dead = TRUE;
}
}
#endif
PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
- m->rebuild_pollfds = 1;
+ m->rebuild_pollfds = TRUE;
m->n_io_events ++;
pa_mainloop_wakeup(m);
@@ -220,7 +222,7 @@ static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
if (e->pollfd)
e->pollfd->events = map_flags_to_libc(events);
else
- e->mainloop->rebuild_pollfds = 1;
+ e->mainloop->rebuild_pollfds = TRUE;
pa_mainloop_wakeup(e->mainloop);
}
@@ -229,11 +231,11 @@ static void mainloop_io_free(pa_io_event *e) {
pa_assert(e);
pa_assert(!e->dead);
- e->dead = 1;
+ e->dead = TRUE;
e->mainloop->io_events_please_scan ++;
e->mainloop->n_io_events --;
- e->mainloop->rebuild_pollfds = 1;
+ e->mainloop->rebuild_pollfds = TRUE;
pa_mainloop_wakeup(e->mainloop);
}
@@ -262,9 +264,9 @@ static pa_defer_event* mainloop_defer_new(
e = pa_xnew(pa_defer_event, 1);
e->mainloop = m;
- e->dead = 0;
+ e->dead = FALSE;
- e->enabled = 1;
+ e->enabled = TRUE;
m->n_enabled_defer_events++;
e->callback = callback;
@@ -297,13 +299,13 @@ static void mainloop_defer_free(pa_defer_event *e) {
pa_assert(e);
pa_assert(!e->dead);
- e->dead = 1;
+ e->dead = TRUE;
e->mainloop->defer_events_please_scan ++;
if (e->enabled) {
pa_assert(e->mainloop->n_enabled_defer_events > 0);
e->mainloop->n_enabled_defer_events--;
- e->enabled = 0;
+ e->enabled = FALSE;
}
}
@@ -333,7 +335,7 @@ static pa_time_event* mainloop_time_new(
e = pa_xnew(pa_time_event, 1);
e->mainloop = m;
- e->dead = 0;
+ e->dead = FALSE;
if ((e->enabled = !!tv)) {
e->timeval = *tv;
@@ -388,13 +390,13 @@ static void mainloop_time_free(pa_time_event *e) {
pa_assert(e);
pa_assert(!e->dead);
- e->dead = 1;
+ e->dead = TRUE;
e->mainloop->time_events_please_scan ++;
if (e->enabled) {
pa_assert(e->mainloop->n_enabled_time_events > 0);
e->mainloop->n_enabled_time_events--;
- e->enabled = 0;
+ e->enabled = FALSE;
}
if (e->mainloop->cached_next_time_event == e)
@@ -462,7 +464,7 @@ pa_mainloop *pa_mainloop_new(void) {
pa_make_fd_nonblock(m->wakeup_pipe[1]);
pa_make_fd_cloexec(m->wakeup_pipe[0]);
pa_make_fd_cloexec(m->wakeup_pipe[1]);
- m->wakeup_requested = 0;
+ m->wakeup_requested = FALSE;
PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
@@ -476,9 +478,10 @@ pa_mainloop *pa_mainloop_new(void) {
m->pollfds = NULL;
m->max_pollfds = m->n_pollfds = 0;
- m->rebuild_pollfds = 1;
+ m->rebuild_pollfds = TRUE;
- m->quit = m->retval = 0;
+ m->quit = FALSE;
+ m->retval = 0;
m->api = vtable;
m->api.userdata = m;
@@ -492,7 +495,7 @@ pa_mainloop *pa_mainloop_new(void) {
return m;
}
-static void cleanup_io_events(pa_mainloop *m, int force) {
+static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
pa_io_event *e;
e = m->io_events;
@@ -515,7 +518,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) {
pa_xfree(e);
- m->rebuild_pollfds = 1;
+ m->rebuild_pollfds = TRUE;
}
e = n;
@@ -524,7 +527,7 @@ static void cleanup_io_events(pa_mainloop *m, int force) {
pa_assert(m->io_events_please_scan == 0);
}
-static void cleanup_time_events(pa_mainloop *m, int force) {
+static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
pa_time_event *e;
e = m->time_events;
@@ -545,7 +548,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) {
if (!e->dead && e->enabled) {
pa_assert(m->n_enabled_time_events > 0);
m->n_enabled_time_events--;
- e->enabled = 0;
+ e->enabled = FALSE;
}
if (e->destroy_callback)
@@ -560,7 +563,7 @@ static void cleanup_time_events(pa_mainloop *m, int force) {
pa_assert(m->time_events_please_scan == 0);
}
-static void cleanup_defer_events(pa_mainloop *m, int force) {
+static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
pa_defer_event *e;
e = m->defer_events;
@@ -581,7 +584,7 @@ static void cleanup_defer_events(pa_mainloop *m, int force) {
if (!e->dead && e->enabled) {
pa_assert(m->n_enabled_defer_events > 0);
m->n_enabled_defer_events--;
- e->enabled = 0;
+ e->enabled = FALSE;
}
if (e->destroy_callback)
@@ -600,9 +603,9 @@ static void cleanup_defer_events(pa_mainloop *m, int force) {
void pa_mainloop_free(pa_mainloop* m) {
pa_assert(m);
- cleanup_io_events(m, 1);
- cleanup_defer_events(m, 1);
- cleanup_time_events(m, 1);
+ cleanup_io_events(m, TRUE);
+ cleanup_defer_events(m, TRUE);
+ cleanup_time_events(m, TRUE);
pa_xfree(m->pollfds);
@@ -615,13 +618,13 @@ static void scan_dead(pa_mainloop *m) {
pa_assert(m);
if (m->io_events_please_scan)
- cleanup_io_events(m, 0);
+ cleanup_io_events(m, FALSE);
if (m->time_events_please_scan)
- cleanup_time_events(m, 0);
+ cleanup_time_events(m, FALSE);
if (m->defer_events_please_scan)
- cleanup_defer_events(m, 0);
+ cleanup_defer_events(m, FALSE);
}
static void rebuild_pollfds(pa_mainloop *m) {
@@ -662,7 +665,7 @@ static void rebuild_pollfds(pa_mainloop *m) {
m->n_pollfds++;
}
- m->rebuild_pollfds = 0;
+ m->rebuild_pollfds = FALSE;
}
static int dispatch_pollfds(pa_mainloop *m) {
@@ -948,7 +951,7 @@ int pa_mainloop_run(pa_mainloop *m, int *retval) {
void pa_mainloop_quit(pa_mainloop *m, int retval) {
pa_assert(m);
- m->quit = 1;
+ m->quit = TRUE;
m->retval = retval;
pa_mainloop_wakeup(m);
}
diff --git a/src/pulse/proplist.c b/src/pulse/proplist.c
index 9e0549ea..93bc0034 100644
--- a/src/pulse/proplist.c
+++ b/src/pulse/proplist.c
@@ -280,7 +280,7 @@ char *pa_proplist_to_string(pa_proplist *p) {
char *c;
pa_assert_se(pa_proplist_get(p, key, &value, &nbytes) == 0);
- c = pa_xnew(char, nbytes*2+1);
+ c = pa_xmalloc(nbytes*2+1);
pa_hexstr((const uint8_t*) value, nbytes, c, nbytes*2+1);
pa_strbuf_printf(buf, "%s = hex:%s\n", key, c);
diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h
index 39d53303..c23ef238 100644
--- a/src/pulse/proplist.h
+++ b/src/pulse/proplist.h
@@ -168,9 +168,19 @@ int pa_proplist_get(pa_proplist *p, const char *key, const void **data, size_t *
/** Update mode enum for pa_proplist_update(). \since 0.9.11 */
typedef enum pa_update_mode {
- PA_UPDATE_SET, /*< Replace the entirey property list with the new one. Don't keep any of the old data around */
- PA_UPDATE_MERGE, /*< Merge new property list into the existing one, not replacing any old entries if they share a common key with the new property list. */
- PA_UPDATE_REPLACE /*< Merge new property list into the existing one, replacing all old entries that share a common key with the new property list. */
+ PA_UPDATE_SET,
+ /*< Replace the entirey property list with the new one. Don't keep
+ * any of the old data around */
+
+ PA_UPDATE_MERGE,
+ /*< Merge new property list into the existing one, not replacing
+ * any old entries if they share a common key with the new
+ * property list. */
+
+ PA_UPDATE_REPLACE
+ /*< Merge new property list into the existing one, replacing all
+ * old entries that share a common key with the new property
+ * list. */
} pa_update_mode_t;
/** Merge property list "other" into "p", adhering the merge mode as
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 2680cf7e..3c7dd0e7 100644
--- a/src/pulse/sample.h
+++ b/src/pulse/sample.h
@@ -120,17 +120,38 @@ PA_C_DECL_BEGIN
/** Sample format */
typedef enum pa_sample_format {
- PA_SAMPLE_U8, /**< Unsigned 8 Bit PCM */
- PA_SAMPLE_ALAW, /**< 8 Bit a-Law */
- PA_SAMPLE_ULAW, /**< 8 Bit mu-Law */
- PA_SAMPLE_S16LE, /**< Signed 16 Bit PCM, little endian (PC) */
- PA_SAMPLE_S16BE, /**< Signed 16 Bit PCM, big endian */
- PA_SAMPLE_FLOAT32LE, /**< 32 Bit IEEE floating point, little endian, range -1 to 1 */
- PA_SAMPLE_FLOAT32BE, /**< 32 Bit IEEE floating point, big endian, range -1 to 1 */
- PA_SAMPLE_S32LE, /**< Signed 32 Bit PCM, little endian (PC) */
- PA_SAMPLE_S32BE, /**< Signed 32 Bit PCM, big endian (PC) */
- PA_SAMPLE_MAX, /**< Upper limit of valid sample types */
- PA_SAMPLE_INVALID = -1 /**< An invalid value */
+ PA_SAMPLE_U8,
+ /**< Unsigned 8 Bit PCM */
+
+ PA_SAMPLE_ALAW,
+ /**< 8 Bit a-Law */
+
+ PA_SAMPLE_ULAW,
+ /**< 8 Bit mu-Law */
+
+ PA_SAMPLE_S16LE,
+ /**< Signed 16 Bit PCM, little endian (PC) */
+
+ PA_SAMPLE_S16BE,
+ /**< Signed 16 Bit PCM, big endian */
+
+ PA_SAMPLE_FLOAT32LE,
+ /**< 32 Bit IEEE floating point, little endian, range -1 to 1 */
+
+ PA_SAMPLE_FLOAT32BE,
+ /**< 32 Bit IEEE floating point, big endian, range -1 to 1 */
+
+ PA_SAMPLE_S32LE,
+ /**< Signed 32 Bit PCM, little endian (PC) */
+
+ PA_SAMPLE_S32BE,
+ /**< Signed 32 Bit PCM, big endian (PC) */
+
+ PA_SAMPLE_MAX,
+ /**< Upper limit of valid sample types */
+
+ PA_SAMPLE_INVALID = -1
+ /**< An invalid value */
} pa_sample_format_t;
#ifdef WORDS_BIGENDIAN
@@ -164,11 +185,29 @@ typedef enum pa_sample_format {
/** A Shortcut for PA_SAMPLE_FLOAT32NE */
#define PA_SAMPLE_FLOAT32 PA_SAMPLE_FLOAT32NE
+/** \cond fulldocs */
+/* Allow clients to check with #ifdef for thse sample formats */
+#define PA_SAMPLE_U8 PA_SAMPLE_U8
+#define PA_SAMPLE_ALAW PA_SAMPLE_ALAW
+#define PA_SAMPLE_ULAW PA_SAMPLE_ULAW
+#define PA_SAMPLE_S16LE PA_SAMPLE_S16LE
+#define PA_SAMPLE_S16BE PA_SAMPLE_S16BE
+#define PA_SAMPLE_FLOAT32LE PA_SAMPLE_FLOAT32LE
+#define PA_SAMPLE_FLOAT32BE PA_SAMPLE_FLOAT32BE
+#define PA_SAMPLE_S32LE PA_SAMPLE_S32LE
+#define PA_SAMPLE_S32BE PA_SAMPLE_S32BE
+/** \endcond */
+
/** A sample format and attribute specification */
typedef struct pa_sample_spec {
- pa_sample_format_t format; /**< The sample format */
- uint32_t rate; /**< The sample rate. (e.g. 44100) */
- uint8_t channels; /**< Audio channels. (1 for mono, 2 for stereo, ...) */
+ pa_sample_format_t format;
+ /**< The sample format */
+
+ uint32_t rate;
+ /**< The sample rate. (e.g. 44100) */
+
+ uint8_t channels;
+ /**< Audio channels. (1 for mono, 2 for stereo, ...) */
} pa_sample_spec;
/** Type for usec specifications (unsigned). Always 64 bit. */
@@ -183,12 +222,21 @@ size_t pa_frame_size(const pa_sample_spec *spec) PA_GCC_PURE;
/** Return the size of a sample with the specific sample type */
size_t pa_sample_size(const pa_sample_spec *spec) PA_GCC_PURE;
-/** Calculate the time the specified bytes take to play with the specified sample type */
+/** Calculate the time the specified bytes take to play with the
+ * specified sample type. The return value will always be rounded
+ * down for non-integral return values. */
pa_usec_t pa_bytes_to_usec(uint64_t length, const pa_sample_spec *spec) PA_GCC_PURE;
-/** Calculates the number of bytes that are required for the specified time. \since 0.9 */
+/** Calculates the number of bytes that are required for the specified
+ * time. The return value will always be rounded down for non-integral
+ * 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;
@@ -201,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/scache.c b/src/pulse/scache.c
index 5e31e7af..fd3b9876 100644
--- a/src/pulse/scache.c
+++ b/src/pulse/scache.c
@@ -47,6 +47,7 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) {
PA_CHECK_VALIDITY(s->context, s->state == PA_STREAM_UNCONNECTED, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY(s->context, length > 0, PA_ERR_INVALID);
+ PA_CHECK_VALIDITY(s->context, length == (size_t) (uint32_t) length, PA_ERR_INVALID);
if (!(name = pa_proplist_gets(s->proplist, PA_PROP_EVENT_ID)))
name = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_NAME);
@@ -63,7 +64,7 @@ int pa_stream_connect_upload(pa_stream *s, size_t length) {
pa_tagstruct_puts(t, name);
pa_tagstruct_put_sample_spec(t, &s->sample_spec);
pa_tagstruct_put_channel_map(t, &s->channel_map);
- pa_tagstruct_putu32(t, length);
+ pa_tagstruct_putu32(t, (uint32_t) length);
if (s->context->version >= 13) {
pa_init_proplist(s->proplist);
diff --git a/src/pulse/simple.c b/src/pulse/simple.c
index 51160ad7..79e39ebb 100644
--- a/src/pulse/simple.c
+++ b/src/pulse/simple.c
@@ -272,7 +272,7 @@ int pa_simple_write(pa_simple *p, const void*data, size_t length, int *rerror) {
if (l > length)
l = length;
- r = pa_stream_write(p->stream, data, l, NULL, 0, PA_SEEK_RELATIVE);
+ r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
CHECK_SUCCESS_GOTO(p, rerror, r >= 0, unlock_and_fail);
data = (const uint8_t*) data + l;
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 585518f0..c0ae4ac2 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);
@@ -124,7 +124,7 @@ pa_stream *pa_stream_new_with_proplist(
* what older PA versions provided. */
s->buffer_attr.maxlength = (uint32_t) -1;
- s->buffer_attr.tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+ s->buffer_attr.tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
s->buffer_attr.minreq = (uint32_t) -1;
s->buffer_attr.prebuf = (uint32_t) -1;
s->buffer_attr.fragsize = (uint32_t) -1;
@@ -315,7 +315,7 @@ static void request_auto_timing_update(pa_stream *s, pa_bool_t force) {
}
}
-void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_command_stream_killed(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
uint32_t channel;
@@ -382,7 +382,7 @@ static void check_smoother_status(pa_stream *s, pa_bool_t aposteriori, pa_bool_t
* if prebuf is non-zero! */
}
-void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_command_stream_moved(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
uint32_t channel;
@@ -479,7 +479,7 @@ finish:
pa_context_unref(c);
}
-void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_command_stream_suspended(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_stream *s;
uint32_t channel;
@@ -557,13 +557,13 @@ 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);
}
-void pa_command_request(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_command_request(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s;
pa_context *c = userdata;
uint32_t bytes, channel;
@@ -598,7 +598,7 @@ finish:
pa_context_unref(c);
}
-void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_command_overflow_or_underflow(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s;
pa_context *c = userdata;
uint32_t channel;
@@ -670,7 +670,7 @@ static void invalidate_indexes(pa_stream *s, pa_bool_t r, pa_bool_t w) {
request_auto_timing_update(s, TRUE);
}
-static void auto_timing_update_callback(PA_GCC_UNUSED pa_mainloop_api *m, PA_GCC_UNUSED pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
+static void auto_timing_update_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) {
pa_stream *s = userdata;
pa_assert(s);
@@ -694,7 +694,7 @@ static void create_stream_complete(pa_stream *s) {
if (s->flags & PA_STREAM_AUTO_TIMING_UPDATE) {
struct timeval tv;
pa_gettimeofday(&tv);
- tv.tv_usec += LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
+ tv.tv_usec += (suseconds_t) LATENCY_IPOL_INTERVAL_USEC; /* every 100 ms */
pa_assert(!s->auto_timing_update_event);
s->auto_timing_update_event = s->mainloop->time_new(s->mainloop, &tv, &auto_timing_update_callback, s);
@@ -722,7 +722,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
attr->maxlength = 4*1024*1024; /* 4MB is the maximum queue length PulseAudio <= 0.9.9 supported. */
if (attr->tlength == (uint32_t) -1)
- attr->tlength = pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
+ attr->tlength = (uint32_t) pa_usec_to_bytes(250*PA_USEC_PER_MSEC, ss); /* 250ms of buffering */
if (attr->minreq == (uint32_t) -1)
attr->minreq = (attr->tlength)/5; /* Ask for more data when there are only 200ms left in the playback buffer */
@@ -734,7 +734,7 @@ static void automatic_buffer_attr(pa_stream *s, pa_buffer_attr *attr, const pa_s
attr->fragsize = attr->tlength; /* Pass data to the app only when the buffer is filled up once */
}
-void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s = userdata;
pa_assert(pd);
@@ -865,6 +865,7 @@ static int create_stream(
pa_tagstruct *t;
uint32_t tag;
+ pa_bool_t volume_set = FALSE;
pa_assert(s);
pa_assert(PA_REFCNT_VALUE(s) >= 1);
@@ -885,7 +886,10 @@ static int create_stream(
PA_STREAM_VARIABLE_RATE|
PA_STREAM_PEAK_DETECT|
PA_STREAM_START_MUTED|
- PA_STREAM_ADJUST_LATENCY)), PA_ERR_INVALID);
+ PA_STREAM_ADJUST_LATENCY|
+ PA_STREAM_EARLY_REQUESTS|
+ PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND|
+ PA_STREAM_START_UNMUTED)), PA_ERR_INVALID);
PA_CHECK_VALIDITY(s->context, s->context->version >= 12 || !(flags & PA_STREAM_VARIABLE_RATE), PA_ERR_NOTSUPPORTED);
PA_CHECK_VALIDITY(s->context, s->context->version >= 13 || !(flags & PA_STREAM_PEAK_DETECT), PA_ERR_NOTSUPPORTED);
@@ -898,6 +902,7 @@ static int create_stream(
PA_CHECK_VALIDITY(s->context, direction == PA_STREAM_RECORD || !(flags & (PA_STREAM_PEAK_DETECT)), PA_ERR_INVALID);
PA_CHECK_VALIDITY(s->context, !volume || volume->channels == s->sample_spec.channels, PA_ERR_INVALID);
PA_CHECK_VALIDITY(s->context, !sync_stream || (direction == PA_STREAM_PLAYBACK && sync_stream->direction == PA_STREAM_PLAYBACK), PA_ERR_INVALID);
+ PA_CHECK_VALIDITY(s->context, (flags & (PA_STREAM_ADJUST_LATENCY|PA_STREAM_EARLY_REQUESTS)) != (PA_STREAM_ADJUST_LATENCY|PA_STREAM_EARLY_REQUESTS), PA_ERR_INVALID);
pa_stream_ref(s);
@@ -930,7 +935,7 @@ static int create_stream(
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CREATE_PLAYBACK_STREAM : PA_COMMAND_CREATE_RECORD_STREAM,
+ (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CREATE_PLAYBACK_STREAM : PA_COMMAND_CREATE_RECORD_STREAM),
&tag);
if (s->context->version < 13)
@@ -957,6 +962,8 @@ static int create_stream(
PA_TAG_U32, s->syncid,
PA_TAG_INVALID);
+ volume_set = !!volume;
+
if (!volume)
volume = pa_cvolume_reset(&cv, s->sample_spec.channels);
@@ -994,6 +1001,22 @@ static int create_stream(
pa_tagstruct_putu32(t, s->direct_on_input);
}
+ if (s->context->version >= 14) {
+
+ if (s->direction == PA_STREAM_PLAYBACK)
+ pa_tagstruct_put_boolean(t, volume_set);
+
+ pa_tagstruct_put_boolean(t, flags & PA_STREAM_EARLY_REQUESTS);
+ }
+
+ if (s->context->version >= 15) {
+
+ if (s->direction == PA_STREAM_PLAYBACK)
+ pa_tagstruct_put_boolean(t, flags & (PA_STREAM_START_MUTED|PA_STREAM_START_UNMUTED));
+
+ pa_tagstruct_put_boolean(t, flags & PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND);
+ }
+
pa_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, pa_create_stream_callback, s, NULL);
@@ -1093,7 +1116,7 @@ int pa_stream_write(
free_cb((void*) data);
if (length < s->requested_bytes)
- s->requested_bytes -= length;
+ s->requested_bytes -= (uint32_t) length;
else
s->requested_bytes = 0;
@@ -1107,10 +1130,10 @@ int pa_stream_write(
if (seek == PA_SEEK_ABSOLUTE) {
s->write_index_corrections[s->current_write_index_correction].corrupt = FALSE;
s->write_index_corrections[s->current_write_index_correction].absolute = TRUE;
- s->write_index_corrections[s->current_write_index_correction].value = offset + length;
+ s->write_index_corrections[s->current_write_index_correction].value = offset + (int64_t) length;
} else if (seek == PA_SEEK_RELATIVE) {
if (!s->write_index_corrections[s->current_write_index_correction].corrupt)
- s->write_index_corrections[s->current_write_index_correction].value += offset + length;
+ s->write_index_corrections[s->current_write_index_correction].value += offset + (int64_t) length;
} else
s->write_index_corrections[s->current_write_index_correction].corrupt = TRUE;
}
@@ -1120,10 +1143,10 @@ int pa_stream_write(
if (seek == PA_SEEK_ABSOLUTE) {
s->timing_info.write_index_corrupt = FALSE;
- s->timing_info.write_index = offset + length;
+ s->timing_info.write_index = offset + (int64_t) length;
} else if (seek == PA_SEEK_RELATIVE) {
if (!s->timing_info.write_index_corrupt)
- s->timing_info.write_index += offset + length;
+ s->timing_info.write_index += offset + (int64_t) length;
} else
s->timing_info.write_index_corrupt = TRUE;
}
@@ -1173,7 +1196,7 @@ int pa_stream_drop(pa_stream *s) {
/* Fix the simulated local read index */
if (s->timing_info_valid && !s->timing_info.read_index_corrupt)
- s->timing_info.read_index += s->peek_memchunk.length;
+ s->timing_info.read_index += (int64_t) s->peek_memchunk.length;
pa_assert(s->peek_data);
pa_memblock_release(s->peek_memchunk.memblock);
@@ -1257,7 +1280,9 @@ static pa_usec_t calc_time(pa_stream *s, pa_bool_t ignore_transport) {
usec -= s->timing_info.sink_usec;
}
- } else if (s->direction == PA_STREAM_RECORD) {
+ } else {
+ pa_assert(s->direction == PA_STREAM_RECORD);
+
/* The last byte written into the server side queue had
* this time value associated */
usec = pa_bytes_to_usec(s->timing_info.write_index < 0 ? 0 : (uint64_t) s->timing_info.write_index, &s->sample_spec);
@@ -1340,7 +1365,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
i->read_index_corrupt = FALSE;
i->playing = (int) playing;
- i->since_underrun = playing ? playing_for : underrun_for;
+ i->since_underrun = (int64_t) (playing ? playing_for : underrun_for);
pa_gettimeofday(&now);
@@ -1418,7 +1443,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
/* Read index correction */
if (!i->read_index_corrupt)
- i->read_index -= pa_memblockq_get_length(o->stream->record_memblockq);
+ i->read_index -= (int64_t) pa_memblockq_get_length(o->stream->record_memblockq);
}
/* Update smoother */
@@ -1435,7 +1460,7 @@ static void stream_get_timing_info_callback(pa_pdispatch *pd, uint32_t command,
* speakers. Since we follow that timing here, we need
* to try to fix this up */
- su = pa_bytes_to_usec(i->since_underrun, &o->stream->sample_spec);
+ su = pa_bytes_to_usec((uint64_t) i->since_underrun, &o->stream->sample_spec);
if (su < i->sink_usec)
x += i->sink_usec - su;
@@ -1494,7 +1519,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY,
+ (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_GET_PLAYBACK_LATENCY : PA_COMMAND_GET_RECORD_LATENCY),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_put_timeval(t, pa_gettimeofday(&now));
@@ -1517,7 +1542,7 @@ pa_operation* pa_stream_update_timing_info(pa_stream *s, pa_stream_success_cb_t
return o;
}
-void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_stream_disconnect_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_stream *s = userdata;
pa_assert(pd);
@@ -1557,8 +1582,8 @@ int pa_stream_disconnect(pa_stream *s) {
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_DELETE_PLAYBACK_STREAM :
- (s->direction == PA_STREAM_RECORD ? PA_COMMAND_DELETE_RECORD_STREAM : PA_COMMAND_DELETE_UPLOAD_STREAM),
+ (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_DELETE_PLAYBACK_STREAM :
+ (s->direction == PA_STREAM_RECORD ? PA_COMMAND_DELETE_RECORD_STREAM : PA_COMMAND_DELETE_UPLOAD_STREAM)),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_pstream_send_tagstruct(s->context->pstream, t);
@@ -1667,7 +1692,7 @@ void pa_stream_set_started_callback(pa_stream *s, pa_stream_notify_cb_t cb, void
s->started_userdata = userdata;
}
-void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_stream_simple_ack_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@@ -1715,7 +1740,7 @@ pa_operation* pa_stream_cork(pa_stream *s, int b, pa_stream_success_cb_t cb, voi
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM,
+ (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_CORK_PLAYBACK_STREAM : PA_COMMAND_CORK_RECORD_STREAM),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_put_boolean(t, !!b);
@@ -1760,7 +1785,7 @@ pa_operation* pa_stream_flush(pa_stream *s, pa_stream_success_cb_t cb, void *use
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE);
- if (!(o = stream_send_simple_command(s, s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM, cb, userdata)))
+ if (!(o = stream_send_simple_command(s, (uint32_t) (s->direction == PA_STREAM_PLAYBACK ? PA_COMMAND_FLUSH_PLAYBACK_STREAM : PA_COMMAND_FLUSH_RECORD_STREAM), cb, userdata)))
return NULL;
if (s->direction == PA_STREAM_PLAYBACK) {
@@ -1836,7 +1861,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 {
@@ -1846,7 +1871,7 @@ pa_operation* pa_stream_set_name(pa_stream *s, const char *name, pa_stream_succe
o = pa_operation_new(s->context, s, (pa_operation_cb_t) cb, userdata);
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME,
+ (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_NAME : PA_COMMAND_SET_PLAYBACK_STREAM_NAME),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_puts(t, name);
@@ -1932,7 +1957,7 @@ int pa_stream_get_latency(pa_stream *s, pa_usec_t *r_usec, int *negative) {
if (cindex < 0)
cindex = 0;
- c = pa_bytes_to_usec(cindex, &s->sample_spec);
+ c = pa_bytes_to_usec((uint64_t) cindex, &s->sample_spec);
if (s->direction == PA_STREAM_PLAYBACK)
*r_usec = time_counter_diff(s, c, t, negative);
@@ -1948,7 +1973,7 @@ const pa_timing_info* pa_stream_get_timing_info(pa_stream *s) {
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->state == PA_STREAM_READY, PA_ERR_BADSTATE);
PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->direction != PA_STREAM_UPLOAD, PA_ERR_BADSTATE);
- PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->timing_info_valid, PA_ERR_BADSTATE);
+ PA_CHECK_VALIDITY_RETURN_NULL(s->context, s->timing_info_valid, PA_ERR_NODATA);
return &s->timing_info;
}
@@ -1978,7 +2003,7 @@ const pa_buffer_attr* pa_stream_get_buffer_attr(pa_stream *s) {
return &s->buffer_attr;
}
-static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void stream_set_buffer_attr_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@@ -1995,7 +2020,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 ||
@@ -2012,6 +2036,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;
@@ -2046,7 +2084,7 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR : PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR,
+ (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR : PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR),
&tag);
pa_tagstruct_putu32(t, s->channel);
@@ -2065,6 +2103,9 @@ pa_operation* pa_stream_set_buffer_attr(pa_stream *s, const pa_buffer_attr *attr
if (s->context->version >= 13)
pa_tagstruct_put_boolean(t, !!(s->flags & PA_STREAM_ADJUST_LATENCY));
+ if (s->context->version >= 14)
+ pa_tagstruct_put_boolean(t, !!(s->flags & PA_STREAM_EARLY_REQUESTS));
+
pa_pstream_send_tagstruct(s->context->pstream, t);
pa_pdispatch_register_reply(s->context->pdispatch, tag, DEFAULT_TIMEOUT, stream_set_buffer_attr_callback, pa_operation_ref(o), (pa_free_cb_t) pa_operation_unref);
@@ -2120,7 +2161,7 @@ int pa_stream_is_corked(pa_stream *s) {
return s->corked;
}
-static void stream_update_sample_rate_callback(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void stream_update_sample_rate_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_operation *o = userdata;
int success = 1;
@@ -2177,7 +2218,7 @@ pa_operation *pa_stream_update_sample_rate(pa_stream *s, uint32_t rate, pa_strea
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE : PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE,
+ (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE : PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_putu32(t, rate);
@@ -2205,7 +2246,7 @@ pa_operation *pa_stream_proplist_update(pa_stream *s, pa_update_mode_t mode, pa_
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST : PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST,
+ (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST : PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST),
&tag);
pa_tagstruct_putu32(t, s->channel);
pa_tagstruct_putu32(t, (uint32_t) mode);
@@ -2238,7 +2279,7 @@ pa_operation *pa_stream_proplist_remove(pa_stream *s, const char *const keys[],
t = pa_tagstruct_command(
s->context,
- s->direction == PA_STREAM_RECORD ? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST : PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST,
+ (uint32_t) (s->direction == PA_STREAM_RECORD ? PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST : PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST),
&tag);
pa_tagstruct_putu32(t, s->channel);
diff --git a/src/pulse/stream.h b/src/pulse/stream.h
index 2a8f7a8b..6cb363c8 100644
--- a/src/pulse/stream.h
+++ b/src/pulse/stream.h
@@ -473,7 +473,7 @@ void pa_stream_set_underflow_callback(pa_stream *p, pa_stream_notify_cb_t cb, vo
/** Set the callback function that is called when a the server starts
* playback after an underrun or on initial startup. This only informs
- * that audio is flowing again, it is no indication that audio startet
+ * that audio is flowing again, it is no indication that audio started
* to reach the speakers already. (Only for playback streams). \since
* 0.9.11 */
void pa_stream_set_started_callback(pa_stream *p, pa_stream_notify_cb_t cb, void *userdata);
diff --git a/src/pulse/subscribe.c b/src/pulse/subscribe.c
index b8d3be89..e12d1446 100644
--- a/src/pulse/subscribe.c
+++ b/src/pulse/subscribe.c
@@ -34,7 +34,7 @@
#include "subscribe.h"
-void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, PA_GCC_UNUSED uint32_t tag, pa_tagstruct *t, void *userdata) {
+void pa_command_subscribe_event(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_context *c = userdata;
pa_subscription_event_type_t e;
uint32_t idx;
diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c
index 9708a735..376cf13c 100644
--- a/src/pulse/timeval.c
+++ b/src/pulse/timeval.c
@@ -90,13 +90,13 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) {
}
/* Calculate the second difference*/
- r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC;
+ r = ((pa_usec_t) a->tv_sec - (pa_usec_t) b->tv_sec) * PA_USEC_PER_SEC;
/* Calculate the microsecond difference */
if (a->tv_usec > b->tv_usec)
- r += ((pa_usec_t) a->tv_usec - b->tv_usec);
+ r += ((pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec);
else if (a->tv_usec < b->tv_usec)
- r -= ((pa_usec_t) b->tv_usec - a->tv_usec);
+ r -= ((pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec);
return r;
}
@@ -132,7 +132,7 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) {
pa_assert(tv);
secs = (unsigned long) (v/PA_USEC_PER_SEC);
- tv->tv_sec += secs;
+ tv->tv_sec += (time_t) secs;
v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC;
tv->tv_usec += (suseconds_t) v;
@@ -140,7 +140,7 @@ struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) {
/* Normalize */
while ((unsigned) tv->tv_usec >= PA_USEC_PER_SEC) {
tv->tv_sec++;
- tv->tv_usec -= PA_USEC_PER_SEC;
+ tv->tv_usec -= (suseconds_t) PA_USEC_PER_SEC;
}
return tv;
@@ -151,14 +151,14 @@ struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) {
pa_assert(tv);
secs = (unsigned long) (v/PA_USEC_PER_SEC);
- tv->tv_sec -= secs;
+ tv->tv_sec -= (time_t) secs;
v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC;
if (tv->tv_usec >= (suseconds_t) v)
tv->tv_usec -= (suseconds_t) v;
else {
tv->tv_sec --;
- tv->tv_usec = tv->tv_usec + PA_USEC_PER_SEC - v;
+ tv->tv_usec += (suseconds_t) (PA_USEC_PER_SEC - v);
}
return tv;
@@ -167,8 +167,8 @@ struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) {
struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) {
pa_assert(tv);
- tv->tv_sec = v / PA_USEC_PER_SEC;
- tv->tv_usec = v % PA_USEC_PER_SEC;
+ tv->tv_sec = (time_t) (v / PA_USEC_PER_SEC);
+ tv->tv_usec = (suseconds_t) (v % PA_USEC_PER_SEC);
return tv;
}
diff --git a/src/pulse/utf8.c b/src/pulse/utf8.c
index 119be542..7671be46 100644
--- a/src/pulse/utf8.c
+++ b/src/pulse/utf8.c
@@ -64,24 +64,24 @@
#define FILTER_CHAR '_'
-static inline int is_unicode_valid(uint32_t ch) {
+static inline pa_bool_t is_unicode_valid(uint32_t ch) {
if (ch >= 0x110000) /* End of unicode space */
- return 0;
+ return FALSE;
if ((ch & 0xFFFFF800) == 0xD800) /* Reserved area for UTF-16 */
- return 0;
+ return FALSE;
if ((ch >= 0xFDD0) && (ch <= 0xFDEF)) /* Reserved */
- return 0;
+ return FALSE;
if ((ch & 0xFFFE) == 0xFFFE) /* BOM (Byte Order Mark) */
- return 0;
+ return FALSE;
- return 1;
+ return TRUE;
}
-static inline int is_continuation_char(uint8_t ch) {
+static inline pa_bool_t is_continuation_char(uint8_t ch) {
if ((ch & 0xc0) != 0x80) /* 10xxxxxx */
- return 0;
- return 1;
+ return FALSE;
+ return TRUE;
}
static inline void merge_continuation_char(uint32_t *u_ch, uint8_t ch) {
@@ -109,17 +109,17 @@ static char* utf8_validate(const char *str, char *output) {
if ((*p & 0xe0) == 0xc0) { /* 110xxxxx two-char seq. */
size = 2;
min = 128;
- val = *p & 0x1e;
+ val = (uint32_t) (*p & 0x1e);
goto ONE_REMAINING;
} else if ((*p & 0xf0) == 0xe0) { /* 1110xxxx three-char seq.*/
size = 3;
min = (1 << 11);
- val = *p & 0x0f;
+ val = (uint32_t) (*p & 0x0f);
goto TWO_REMAINING;
} else if ((*p & 0xf8) == 0xf0) { /* 11110xxx four-char seq */
size = 4;
min = (1 << 16);
- val = *p & 0x07;
+ val = (uint32_t) (*p & 0x07);
} else {
size = 1;
goto error;
@@ -149,7 +149,7 @@ ONE_REMAINING:
goto error;
if (o) {
- memcpy(o, last, size);
+ memcpy(o, last, (size_t) size);
o += size - 1;
}
@@ -189,7 +189,7 @@ char* pa_utf8_filter (const char *str) {
char *new_str;
pa_assert(str);
- new_str = pa_xnew(char, strlen(str) + 1);
+ new_str = pa_xmalloc(strlen(str) + 1);
return utf8_validate(str, new_str);
}
@@ -212,7 +212,7 @@ static char* iconv_simple(const char *str, const char *to, const char *from) {
return NULL;
inlen = len = strlen(str) + 1;
- new_str = pa_xnew(char, len);
+ new_str = pa_xmalloc(len);
for (;;) {
inbuf = (ICONV_CONST char*) str; /* Brain dead prototype for iconv() */
diff --git a/src/pulse/util.c b/src/pulse/util.c
index f785a2e9..b20ea46a 100644
--- a/src/pulse/util.c
+++ b/src/pulse/util.c
@@ -95,12 +95,15 @@ char *pa_get_user_name(char *s, size_t l) {
#elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
DWORD size = sizeof(buf);
- if (!GetUserName(buf, &size))
+ if (!GetUserName(buf, &size)) {
+ errno = ENOENT;
return NULL;
+ }
p = buf;
#else /* HAVE_PWD_H */
+
return NULL;
#endif /* HAVE_PWD_H */
}
@@ -138,6 +141,8 @@ char *pa_get_home_dir(char *s, size_t l) {
return pa_strlcpy(s, e, l);
#ifdef HAVE_PWD_H
+
+ errno = 0;
#ifdef HAVE_GETPWUID_R
if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
#else
@@ -145,11 +150,16 @@ char *pa_get_home_dir(char *s, size_t l) {
* that do not support getpwuid_r. */
if ((r = getpwuid(getuid())) == NULL) {
#endif
+ if (!errno)
+ errno = ENOENT;
+
return NULL;
}
return pa_strlcpy(s, r->pw_dir, l);
#else /* HAVE_PWD_H */
+
+ errno = ENOENT;
return NULL;
#endif
}
@@ -200,6 +210,7 @@ char *pa_get_binary_name(char *s, size_t l) {
}
#endif
+ errno = ENOENT;
return NULL;
}
@@ -249,8 +260,8 @@ int pa_msleep(unsigned long t) {
#elif defined(HAVE_NANOSLEEP)
struct timespec ts;
- ts.tv_sec = t/1000;
- ts.tv_nsec = (t % 1000) * 1000000;
+ ts.tv_sec = (time_t) (t/1000UL);
+ ts.tv_nsec = (long) ((t % 1000UL) * 1000000UL);
return nanosleep(&ts, NULL);
#else
diff --git a/src/pulse/volume.c b/src/pulse/volume.c
index 625eb19a..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;
@@ -53,7 +67,7 @@ pa_cvolume* pa_cvolume_set(pa_cvolume *a, unsigned channels, pa_volume_t v) {
pa_assert(channels > 0);
pa_assert(channels <= PA_CHANNELS_MAX);
- a->channels = channels;
+ a->channels = (uint8_t) channels;
for (i = 0; i < a->channels; i++)
a->values[i] = v;
@@ -74,8 +88,29 @@ pa_volume_t pa_cvolume_avg(const pa_cvolume *a) {
return (pa_volume_t) sum;
}
+pa_volume_t pa_cvolume_max(const pa_cvolume *a) {
+ pa_volume_t m = 0;
+ int i;
+ pa_assert(a);
+
+ for (i = 0; i < a->channels; i++)
+ if (a->values[i] > m)
+ m = a->values[i];
+
+ return m;
+}
+
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
@@ -84,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) {
@@ -110,18 +145,25 @@ double pa_sw_volume_to_linear(pa_volume_t v) {
if (v == PA_VOLUME_MUTED)
return 0;
- return pow(10, pa_sw_volume_to_dB(v)/20);
+ return pow(10.0, pa_sw_volume_to_dB(v)/20.0);
}
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++) {
@@ -131,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;
@@ -156,24 +229,41 @@ 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;
- dest->channels = 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;
return dest;
}
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;
}
@@ -261,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 4fdbf658..75051af5 100644
--- a/src/pulse/volume.h
+++ b/src/pulse/volume.h
@@ -62,7 +62,7 @@
*
* The functions described above are only valid when used with
* software volumes. Hence it is usually a better idea to treat all
- * volume values as opaque with a range from PA_VOLUME_MUTE (0%) to
+ * volume values as opaque with a range from PA_VOLUME_MUTED (0%) to
* PA_VOLUME_NORM (100%) and to refrain from any calculations with
* them.
*
@@ -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,15 +130,32 @@ 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;
+/** Return the maximum volume of all channels. \since 0.9.12 */
+pa_volume_t pa_cvolume_max(const pa_cvolume *a) PA_GCC_PURE;
+
/** Return TRUE when the passed cvolume structure is valid, FALSE otherwise */
int pa_cvolume_valid(const pa_cvolume *v) PA_GCC_PURE;
@@ -146,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;
@@ -174,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/pulse/xmalloc.c b/src/pulse/xmalloc.c
index 90237013..c570e40f 100644
--- a/src/pulse/xmalloc.c
+++ b/src/pulse/xmalloc.c
@@ -36,7 +36,7 @@
#include "xmalloc.h"
/* Make sure not to allocate more than this much memory. */
-#define MAX_ALLOC_SIZE (1024*1024*20) /* 20MB */
+#define MAX_ALLOC_SIZE (1024*1024*96) /* 96MB */
/* #undef malloc */
/* #undef free */
@@ -46,7 +46,7 @@
static void oom(void) PA_GCC_NORETURN;
-/** called in case of an OOM situation. Prints an error message and
+/* called in case of an OOM situation. Prints an error message and
* exits */
static void oom(void) {
static const char e[] = "Not enough memory\n";
@@ -113,7 +113,7 @@ char *pa_xstrndup(const char *s, size_t l) {
return NULL;
if ((e = memchr(s, 0, l)))
- return pa_xmemdup(s, e-s+1);
+ return pa_xmemdup(s, (size_t) (e-s+1));
r = pa_xmalloc(l+1);
memcpy(r, s, l);
diff --git a/src/pulse/xmalloc.h b/src/pulse/xmalloc.h
index c453138b..b2643588 100644
--- a/src/pulse/xmalloc.h
+++ b/src/pulse/xmalloc.h
@@ -26,7 +26,9 @@
#include <stdlib.h>
#include <limits.h>
#include <assert.h>
+
#include <pulse/cdecl.h>
+#include <pulse/gccmacro.h>
/** \file
* Memory allocation functions.
@@ -35,52 +37,58 @@
PA_C_DECL_BEGIN
/** Allocate the specified number of bytes, just like malloc() does. However, in case of OOM, terminate */
-void* pa_xmalloc(size_t l);
+void* pa_xmalloc(size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(1);
/** Same as pa_xmalloc(), but initialize allocated memory to 0 */
-void *pa_xmalloc0(size_t l);
+void *pa_xmalloc0(size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(1);
/** The combination of pa_xmalloc() and realloc() */
-void *pa_xrealloc(void *ptr, size_t size);
+void *pa_xrealloc(void *ptr, size_t size) PA_GCC_ALLOC_SIZE(2);
/** Free allocated memory */
void pa_xfree(void *p);
/** Duplicate the specified string, allocating memory with pa_xmalloc() */
-char *pa_xstrdup(const char *s);
+char *pa_xstrdup(const char *s) PA_GCC_MALLOC;
/** Duplicate the specified string, but truncate after l characters */
-char *pa_xstrndup(const char *s, size_t l);
+char *pa_xstrndup(const char *s, size_t l) PA_GCC_MALLOC;
/** Duplicate the specified memory block */
-void* pa_xmemdup(const void *p, size_t l);
+void* pa_xmemdup(const void *p, size_t l) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE(2);
/** Internal helper for pa_xnew() */
-static inline void* pa_xnew_internal(unsigned n, size_t k) {
+static void* _pa_xnew_internal(size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(1,2);
+
+static inline void* _pa_xnew_internal(size_t n, size_t k) {
assert(n < INT_MAX/k);
return pa_xmalloc(n*k);
}
/** Allocate n new structures of the specified type. */
-#define pa_xnew(type, n) ((type*) pa_xnew_internal((n), sizeof(type)))
+#define pa_xnew(type, n) ((type*) _pa_xnew_internal((n), sizeof(type)))
/** Internal helper for pa_xnew0() */
-static inline void* pa_xnew0_internal(unsigned n, size_t k) {
+static void* _pa_xnew0_internal(size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(1,2);
+
+static inline void* _pa_xnew0_internal(size_t n, size_t k) {
assert(n < INT_MAX/k);
return pa_xmalloc0(n*k);
}
/** Same as pa_xnew() but set the memory to zero */
-#define pa_xnew0(type, n) ((type*) pa_xnew0_internal((n), sizeof(type)))
+#define pa_xnew0(type, n) ((type*) _pa_xnew0_internal((n), sizeof(type)))
/** Internal helper for pa_xnew0() */
-static inline void* pa_xnewdup_internal(const void *p, unsigned n, size_t k) {
+static void* _pa_xnewdup_internal(const void *p, size_t n, size_t k) PA_GCC_MALLOC PA_GCC_ALLOC_SIZE2(2,3);
+
+static inline void* _pa_xnewdup_internal(const void *p, size_t n, size_t k) {
assert(n < INT_MAX/k);
return pa_xmemdup(p, n*k);
}
/** Same as pa_xnew() but set the memory to zero */
-#define pa_xnewdup(type, p, n) ((type*) pa_xnewdup_internal((p), (n), sizeof(type)))
+#define pa_xnewdup(type, p, n) ((type*) _pa_xnewdup_internal((p), (n), sizeof(type)))
PA_C_DECL_END
diff --git a/src/pulsecore/asyncq.c b/src/pulsecore/asyncq.c
index 03e9f0df..f64931a5 100644
--- a/src/pulsecore/asyncq.c
+++ b/src/pulsecore/asyncq.c
@@ -71,7 +71,7 @@ PA_STATIC_FLIST_DECLARE(localq, 0, pa_xfree);
#define PA_ASYNCQ_CELLS(x) ((pa_atomic_ptr_t*) ((uint8_t*) (x) + PA_ALIGN(sizeof(struct pa_asyncq))))
-static int reduce(pa_asyncq *l, int value) {
+static unsigned reduce(pa_asyncq *l, unsigned value) {
return value & (unsigned) (l->size - 1);
}
@@ -132,7 +132,7 @@ void pa_asyncq_free(pa_asyncq *l, pa_free_cb_t free_cb) {
}
static int push(pa_asyncq*l, void *p, pa_bool_t wait) {
- int idx;
+ unsigned idx;
pa_atomic_ptr_t *cells;
pa_assert(l);
@@ -220,7 +220,7 @@ void pa_asyncq_post(pa_asyncq*l, void *p) {
}
void* pa_asyncq_pop(pa_asyncq*l, pa_bool_t wait) {
- int idx;
+ unsigned idx;
void *ret;
pa_atomic_ptr_t *cells;
@@ -263,7 +263,7 @@ int pa_asyncq_read_fd(pa_asyncq *q) {
}
int pa_asyncq_read_before_poll(pa_asyncq *l) {
- int idx;
+ unsigned idx;
pa_atomic_ptr_t *cells;
pa_assert(l);
@@ -280,8 +280,6 @@ int pa_asyncq_read_before_poll(pa_asyncq *l) {
if (pa_fdsem_before_poll(l->write_fdsem) >= 0)
return 0;
}
-
- return 0;
}
void pa_asyncq_read_after_poll(pa_asyncq *l) {
diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h
index a91c4d56..9c58c661 100644
--- a/src/pulsecore/atomic.h
+++ b/src/pulsecore/atomic.h
@@ -23,6 +23,8 @@
USA.
***/
+#include <pulsecore/macro.h>
+
/*
* atomic_ops guarantees us that sizeof(AO_t) == sizeof(void*). It is
* not guaranteed however, that sizeof(AO_t) == sizeof(size_t).
@@ -35,7 +37,7 @@
* On gcc >= 4.1 we use the builtin atomic functions. otherwise we use
* libatomic_ops
*/
-#
+
#ifndef PACKAGE
#error "Please include config.h before including this file!"
#endif
@@ -80,8 +82,8 @@ static inline int pa_atomic_dec(pa_atomic_t *a) {
return pa_atomic_sub(a, 1);
}
-/* Returns non-zero when the operation was successful. */
-static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
+/* Returns TRUE when the operation was successful. */
+static inline pa_bool_t pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
return __sync_bool_compare_and_swap(&a->value, old_i, new_i);
}
@@ -101,13 +103,13 @@ static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {
__sync_synchronize();
}
-static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
+static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
return __sync_bool_compare_and_swap(&a->value, (long) old_p, (long) new_p);
}
#elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
-#error "The native atomic operations implementation for AMD64 has not been tested. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: make the native atomic operations implementation for AMD64 work, fix libatomic_ops, or upgrade your GCC."
+#warn "The native atomic operations implementation for AMD64 has not been tested thoroughly. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: test the native atomic operations implementation for AMD64, fix libatomic_ops, or upgrade your GCC."
/* Addapted from glibc */
@@ -147,14 +149,14 @@ static inline int pa_atomic_dec(pa_atomic_t *a) {
return pa_atomic_sub(a, 1);
}
-static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
+static inline pa_bool_t pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
int result;
__asm__ __volatile__ ("lock; cmpxchgl %2, %1"
: "=a" (result), "=m" (a->value)
: "r" (new_i), "m" (a->value), "0" (old_i));
- return result == oldval;
+ return result == old_i;
}
typedef struct pa_atomic_ptr {
@@ -171,14 +173,14 @@ static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {
a->value = (unsigned long) p;
}
-static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
+static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
void *result;
__asm__ __volatile__ ("lock; cmpxchgq %q2, %1"
: "=a" (result), "=m" (a->value)
: "r" (new_p), "m" (a->value), "0" (old_p));
- return result;
+ return result == old_p;
}
#elif defined(ATOMIC_ARM_INLINE_ASM)
@@ -255,7 +257,7 @@ static inline int pa_atomic_dec(pa_atomic_t *a) {
return pa_atomic_sub(a, 1);
}
-static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
+static inline pa_bool_t pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
unsigned long not_equal, not_exclusive;
pa_memory_barrier();
@@ -289,7 +291,7 @@ static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {
pa_memory_barrier();
}
-static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
+static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
unsigned long not_equal, not_exclusive;
pa_memory_barrier();
@@ -377,8 +379,8 @@ static inline int pa_atomic_dec(pa_atomic_t *a) {
return pa_atomic_sub(a, 1);
}
-/* Returns non-zero when the operation was successful. */
-static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
+/* Returns TRUE when the operation was successful. */
+static inline pa_bool_t pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
pa_bool_t failed;
do {
failed = !!__kernel_cmpxchg(old_i, new_i, &a->value);
@@ -402,7 +404,7 @@ static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {
pa_memory_barrier();
}
-static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
+static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
pa_bool_t failed;
do {
failed = !!__kernel_cmpxchg_u((unsigned long) old_p, (unsigned long) new_p, &a->value);
@@ -420,7 +422,7 @@ typedef struct pa_atomic {
volatile AO_t value;
} pa_atomic_t;
-#define PA_ATOMIC_INIT(v) { .value = (v) }
+#define PA_ATOMIC_INIT(v) { .value = (AO_t) (v) }
static inline int pa_atomic_load(const pa_atomic_t *a) {
return (int) AO_load_full((AO_t*) &a->value);
@@ -431,23 +433,23 @@ static inline void pa_atomic_store(pa_atomic_t *a, int i) {
}
static inline int pa_atomic_add(pa_atomic_t *a, int i) {
- return AO_fetch_and_add_full(&a->value, (AO_t) i);
+ return (int) AO_fetch_and_add_full(&a->value, (AO_t) i);
}
static inline int pa_atomic_sub(pa_atomic_t *a, int i) {
- return AO_fetch_and_add_full(&a->value, (AO_t) -i);
+ return (int) AO_fetch_and_add_full(&a->value, (AO_t) -i);
}
static inline int pa_atomic_inc(pa_atomic_t *a) {
- return AO_fetch_and_add1_full(&a->value);
+ return (int) AO_fetch_and_add1_full(&a->value);
}
static inline int pa_atomic_dec(pa_atomic_t *a) {
- return AO_fetch_and_sub1_full(&a->value);
+ return (int) AO_fetch_and_sub1_full(&a->value);
}
-static inline int pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
- return AO_compare_and_swap_full(&a->value, old_i, new_i);
+static inline pa_bool_t pa_atomic_cmpxchg(pa_atomic_t *a, int old_i, int new_i) {
+ return AO_compare_and_swap_full(&a->value, (unsigned long) old_i, (unsigned long) new_i);
}
typedef struct pa_atomic_ptr {
@@ -464,7 +466,7 @@ static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void *p) {
AO_store_full(&a->value, (AO_t) p);
}
-static inline int pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
+static inline pa_bool_t pa_atomic_ptr_cmpxchg(pa_atomic_ptr_t *a, void *old_p, void* new_p) {
return AO_compare_and_swap_full(&a->value, (AO_t) old_p, (AO_t) new_p);
}
diff --git a/src/pulsecore/authkey.c b/src/pulsecore/authkey.c
index f3f40f80..b122feee 100644
--- a/src/pulsecore/authkey.c
+++ b/src/pulsecore/authkey.c
@@ -54,8 +54,8 @@ static int generate(int fd, void *ret_data, size_t length) {
pa_random(ret_data, length);
- lseek(fd, 0, SEEK_SET);
- (void) ftruncate(fd, 0);
+ lseek(fd, (off_t) 0, SEEK_SET);
+ (void) ftruncate(fd, (off_t) 0);
if ((r = pa_loop_write(fd, ret_data, length, NULL)) < 0 || (size_t) r != length) {
pa_log("Failed to write cookie file: %s", pa_cstrerror(errno));
@@ -88,7 +88,7 @@ static int load(const char *fn, void *data, size_t length) {
if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) {
if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY|O_NOCTTY)) < 0) {
- pa_log("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
+ pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
goto finish;
} else
writable = 0;
@@ -105,7 +105,7 @@ static int load(const char *fn, void *data, size_t length) {
pa_log_debug("Got %d bytes from cookie file '%s', expected %d", (int) r, fn, (int) length);
if (!writable) {
- pa_log("Unable to write cookie to read only file");
+ pa_log_warn("Unable to write cookie to read-only file");
goto finish;
}
@@ -140,7 +140,7 @@ int pa_authkey_load(const char *path, void *data, size_t length) {
pa_assert(length > 0);
if ((ret = load(path, data, length)) < 0)
- pa_log("Failed to load authorization key '%s': %s", path, (ret < 0) ? pa_cstrerror(errno) : "File corrupt");
+ pa_log_warn("Failed to load authorization key '%s': %s", path, (ret < 0) ? pa_cstrerror(errno) : "File corrupt");
return ret;
}
@@ -206,7 +206,7 @@ int pa_authkey_save(const char *fn, const void *data, size_t length) {
return -2;
if ((fd = open(p, O_RDWR|O_CREAT|O_NOCTTY, S_IRUSR|S_IWUSR)) < 0) {
- pa_log("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
+ pa_log_warn("Failed to open cookie file '%s': %s", fn, pa_cstrerror(errno));
goto finish;
}
diff --git a/src/pulsecore/autoload.c b/src/pulsecore/autoload.c
index 26c294b2..8c84cee5 100644
--- a/src/pulsecore/autoload.c
+++ b/src/pulsecore/autoload.c
@@ -158,7 +158,7 @@ void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type) {
e->in_action = 0;
}
-static void free_func(void *p, PA_GCC_UNUSED void *userdata) {
+static void free_func(void *p, void *userdata) {
pa_autoload_entry *e = p;
pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL);
entry_free(e);
diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index a80933fa..b5ff98db 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -117,6 +117,10 @@ static int pa_cli_command_vacuum(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa
static int pa_cli_command_suspend_sink(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
static int pa_cli_command_suspend_source(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
/* A method table for all available commands */
@@ -167,6 +171,10 @@ static const struct command commands[] = {
{ "suspend-sink", pa_cli_command_suspend_sink, "Suspend sink (args: index|name, bool)", 3},
{ "suspend-source", pa_cli_command_suspend_source, "Suspend source (args: index|name, bool)", 3},
{ "suspend", pa_cli_command_suspend, "Suspend all sinks and all sources (args: bool)", 2},
+ { "set-log-level", pa_cli_command_log_level, "Change the log level (args: numeric level)", 2},
+ { "set-log-meta", pa_cli_command_log_meta, "Show source code location in log messages (args: bool)", 2},
+ { "set-log-time", pa_cli_command_log_time, "Show timestamps in log messages (args: bool)", 2},
+ { "set-log-backtrace", pa_cli_command_log_backtrace, "Show bakctrace in log messages (args: frames)", 2},
{ NULL, NULL, NULL, 0 }
};
@@ -318,22 +326,22 @@ static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_allocated),
- pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->allocated_size)));
+ pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->allocated_size)));
pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_accumulated),
- pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->accumulated_size)));
+ pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->accumulated_size)));
pa_strbuf_printf(buf, "Memory blocks imported from other processes: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_imported),
- pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->imported_size)));
+ pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->imported_size)));
pa_strbuf_printf(buf, "Memory blocks exported to other processes: %u, size: %s.\n",
(unsigned) pa_atomic_load(&stat->n_exported),
- pa_bytes_snprint(s, sizeof(s), (size_t) pa_atomic_load(&stat->exported_size)));
+ pa_bytes_snprint(s, sizeof(s), (unsigned) pa_atomic_load(&stat->exported_size)));
pa_strbuf_printf(buf, "Total sample cache size: %s.\n",
- pa_bytes_snprint(s, sizeof(s), pa_scache_total_size(c)));
+ pa_bytes_snprint(s, sizeof(s), (unsigned) pa_scache_total_size(c)));
pa_strbuf_printf(buf, "Default sample spec: %s\n",
pa_sample_spec_snprint(s, sizeof(s), &c->default_sample_spec));
@@ -1203,6 +1211,102 @@ static int pa_cli_command_suspend(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, p
return 0;
}
+static int pa_cli_command_log_level(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+ const char *m;
+ uint32_t level;
+
+ pa_core_assert_ref(c);
+ pa_assert(t);
+ pa_assert(buf);
+ pa_assert(fail);
+
+ if (!(m = pa_tokenizer_get(t, 1))) {
+ pa_strbuf_puts(buf, "You need to specify a log level (0..4).\n");
+ return -1;
+ }
+
+ if (pa_atou(m, &level) < 0 || level >= PA_LOG_LEVEL_MAX) {
+ pa_strbuf_puts(buf, "Failed to parse log level.\n");
+ return -1;
+ }
+
+ pa_log_set_maximal_level(level);
+
+ return 0;
+}
+
+static int pa_cli_command_log_meta(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+ const char *m;
+ pa_bool_t b;
+
+ pa_core_assert_ref(c);
+ pa_assert(t);
+ pa_assert(buf);
+ pa_assert(fail);
+
+ if (!(m = pa_tokenizer_get(t, 1))) {
+ pa_strbuf_puts(buf, "You need to specify a boolean.\n");
+ return -1;
+ }
+
+ if ((b = pa_parse_boolean(m)) < 0) {
+ pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
+ return -1;
+ }
+
+ pa_log_set_show_meta(b);
+
+ return 0;
+}
+
+static int pa_cli_command_log_time(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+ const char *m;
+ pa_bool_t b;
+
+ pa_core_assert_ref(c);
+ pa_assert(t);
+ pa_assert(buf);
+ pa_assert(fail);
+
+ if (!(m = pa_tokenizer_get(t, 1))) {
+ pa_strbuf_puts(buf, "You need to specify a boolean.\n");
+ return -1;
+ }
+
+ if ((b = pa_parse_boolean(m)) < 0) {
+ pa_strbuf_puts(buf, "Failed to parse log meta switch.\n");
+ return -1;
+ }
+
+ pa_log_set_show_time(b);
+
+ return 0;
+}
+
+static int pa_cli_command_log_backtrace(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+ const char *m;
+ uint32_t nframes;
+
+ pa_core_assert_ref(c);
+ pa_assert(t);
+ pa_assert(buf);
+ pa_assert(fail);
+
+ if (!(m = pa_tokenizer_get(t, 1))) {
+ pa_strbuf_puts(buf, "You need to specify a backtrace level.\n");
+ return -1;
+ }
+
+ if (pa_atou(m, &nframes) < 0 || nframes >= 1000) {
+ pa_strbuf_puts(buf, "Failed to parse backtrace level.\n");
+ return -1;
+ }
+
+ pa_log_set_show_backtrace(nframes);
+
+ return 0;
+}
+
static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
pa_module *m;
pa_sink *sink;
@@ -1251,8 +1355,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
nl = 1;
}
- pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink)));
- pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink)));
+ pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, FALSE)));
+ pa_strbuf_printf(buf, "set-sink-mute %s %s\n", sink->name, pa_yes_no(pa_sink_get_mute(sink, FALSE)));
pa_strbuf_printf(buf, "suspend-sink %s %s\n", sink->name, pa_yes_no(pa_sink_get_state(sink) == PA_SINK_SUSPENDED));
}
@@ -1265,8 +1369,8 @@ static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_b
nl = 1;
}
- pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source)));
- pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source)));
+ pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, FALSE)));
+ pa_strbuf_printf(buf, "set-source-mute %s %s\n", source->name, pa_yes_no(pa_source_get_mute(source, FALSE)));
pa_strbuf_printf(buf, "suspend-source %s %s\n", source->name, pa_yes_no(pa_source_get_state(source) == PA_SOURCE_SUSPENDED));
}
diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c
index c92fca20..7bbc2660 100644
--- a/src/pulsecore/cli-text.c
+++ b/src/pulsecore/cli-text.c
@@ -149,10 +149,12 @@ char *pa_sink_list_to_string(pa_core *c) {
sink->flags & PA_SINK_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "",
sink->flags & PA_SINK_LATENCY ? "LATENCY " : "",
state_table[pa_sink_get_state(sink)],
- pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink)),
- pa_yes_no(pa_sink_get_mute(sink)),
- (double) pa_sink_get_latency(sink) / PA_USEC_PER_MSEC,
- (double) pa_sink_get_requested_latency(sink) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC,
+ pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, FALSE)),
+ pa_yes_no(pa_sink_get_mute(sink, FALSE)),
+ (double) pa_sink_get_latency(sink) / (double) PA_USEC_PER_MSEC,
+ (double) pa_sink_get_requested_latency(sink) / (double) PA_USEC_PER_MSEC,
+ (double) min_latency / PA_USEC_PER_MSEC,
+ (double) max_latency / PA_USEC_PER_MSEC,
(unsigned long) pa_sink_get_max_request(sink) / 1024,
(unsigned long) pa_sink_get_max_rewind(sink) / 1024,
sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX,
@@ -222,10 +224,12 @@ char *pa_source_list_to_string(pa_core *c) {
source->flags & PA_SOURCE_DECIBEL_VOLUME ? "DECIBEL_VOLUME " : "",
source->flags & PA_SOURCE_LATENCY ? "LATENCY " : "",
state_table[pa_source_get_state(source)],
- pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source)),
- pa_yes_no(pa_source_get_mute(source)),
+ pa_cvolume_snprint(cv, sizeof(cv), pa_source_get_volume(source, FALSE)),
+ pa_yes_no(pa_source_get_mute(source, FALSE)),
(double) pa_source_get_latency(source) / PA_USEC_PER_MSEC,
- (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC, (double) min_latency / PA_USEC_PER_MSEC, (double) max_latency / PA_USEC_PER_MSEC,
+ (double) pa_source_get_requested_latency(source) / PA_USEC_PER_MSEC,
+ (double) min_latency / PA_USEC_PER_MSEC,
+ (double) max_latency / PA_USEC_PER_MSEC,
(unsigned long) pa_source_get_max_rewind(source) / 1024,
pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec),
pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map),
@@ -411,7 +415,7 @@ char *pa_scache_list_to_string(pa_core *c) {
if (e->memchunk.memblock) {
pa_sample_spec_snprint(ss, sizeof(ss), &e->sample_spec);
pa_channel_map_snprint(cm, sizeof(cm), &e->channel_map);
- l = (double) e->memchunk.length / pa_bytes_per_second(&e->sample_spec);
+ l = (double) e->memchunk.length / (double) pa_bytes_per_second(&e->sample_spec);
}
pa_strbuf_printf(
diff --git a/src/pulsecore/conf-parser.c b/src/pulsecore/conf-parser.c
index 4aec45d7..ef6d6bb6 100644
--- a/src/pulsecore/conf-parser.c
+++ b/src/pulsecore/conf-parser.c
@@ -148,7 +148,7 @@ finish:
return r;
}
-int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
int *i = data;
int32_t k;
@@ -166,7 +166,43 @@ int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue,
return 0;
}
-int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+int pa_config_parse_unsigned(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
+ unsigned *u = 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;
+ }
+
+ *u = (unsigned) k;
+ 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;
@@ -185,7 +221,7 @@ int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue
return 0;
}
-int pa_config_parse_string(const char *filename, PA_GCC_UNUSED unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) {
+int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata) {
char **s = data;
pa_assert(filename);
diff --git a/src/pulsecore/conf-parser.h b/src/pulsecore/conf-parser.h
index 7eb1fae2..48a0fd26 100644
--- a/src/pulsecore/conf-parser.h
+++ b/src/pulsecore/conf-parser.h
@@ -39,8 +39,10 @@ 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_unsigned(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 75fa2ff1..1d080e11 100644
--- a/src/pulsecore/core-scache.c
+++ b/src/pulsecore/core-scache.c
@@ -63,7 +63,7 @@
#define UNLOAD_POLL_TIME 60
-static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
+static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) {
pa_core *c = userdata;
struct timeval ntv;
@@ -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)
@@ -282,7 +285,7 @@ int pa_scache_remove_item(pa_core *c, const char *name) {
return 0;
}
-static void free_cb(void *p, PA_GCC_UNUSED void *userdata) {
+static void free_cb(void *p, void *userdata) {
pa_scache_entry *e = p;
pa_assert(e);
@@ -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-subscribe.c b/src/pulsecore/core-subscribe.c
index 6107002b..c70d8adc 100644
--- a/src/pulsecore/core-subscribe.c
+++ b/src/pulsecore/core-subscribe.c
@@ -42,7 +42,7 @@
struct pa_subscription {
pa_core *core;
- int dead;
+ pa_bool_t dead;
pa_subscription_cb_t callback;
void *userdata;
@@ -72,7 +72,7 @@ pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, pa_su
s = pa_xnew(pa_subscription, 1);
s->core = c;
- s->dead = 0;
+ s->dead = FALSE;
s->callback = callback;
s->userdata = userdata;
s->mask = m;
@@ -86,7 +86,7 @@ void pa_subscription_free(pa_subscription*s) {
pa_assert(s);
pa_assert(!s->dead);
- s->dead = 1;
+ s->dead = TRUE;
sched_event(s->core);
}
@@ -145,7 +145,7 @@ static void dump_event(const char * prefix, pa_subscription_event*e) {
[PA_SUBSCRIPTION_EVENT_REMOVE] = "REMOVE"
};
- pa_log("%s event (%s|%s|%u)",
+ pa_log_debug("%s event (%s|%s|%u)",
prefix,
fac_table[e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK],
type_table[e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK],
@@ -234,7 +234,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
* entry in the queue. */
free_event(i);
- pa_log_debug("dropped redundant event.");
+ pa_log_debug("Dropped redundant event due to remove event.");
continue;
}
@@ -242,7 +242,7 @@ void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t i
/* This object has changed. If a "new" or "change" event for
* this object is still in the queue we can exit. */
- pa_log_debug("dropped redundant event.");
+ pa_log_debug("Dropped redundant event due to change event.");
return;
}
}
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index b2c91e45..dde34d7b 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -40,6 +40,9 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <dirent.h>
+#include <regex.h>
+#include <langinfo.h>
+#include <sys/utsname.h>
#ifdef HAVE_STRTOF_L
#include <locale.h>
@@ -111,6 +114,8 @@ int pa_set_root(HANDLE handle) {
strcpy(library_path, PULSE_ROOTENV "=");
+ /* FIXME: Needs to set errno */
+
if (!GetModuleFileName(handle, library_path + sizeof(PULSE_ROOTENV), MAX_PATH))
return 0;
@@ -168,7 +173,7 @@ void pa_make_fd_cloexec(int fd) {
/** Creates a directory securely */
int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
struct stat st;
- int r;
+ int r, saved_errno;
pa_assert(dir);
@@ -220,7 +225,10 @@ int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid) {
return 0;
fail:
+ saved_errno = errno;
rmdir(dir);
+ errno = saved_errno;
+
return -1;
}
@@ -230,6 +238,7 @@ char *pa_parent_dir(const char *fn) {
if ((slash = (char*) pa_path_get_filename(dir)) == dir) {
pa_xfree(dir);
+ errno = ENOENT;
return NULL;
}
@@ -337,7 +346,7 @@ ssize_t pa_loop_read(int fd, void*data, size_t size, int *type) {
ret += r;
data = (uint8_t*) data + r;
- size -= r;
+ size -= (size_t) r;
}
return ret;
@@ -368,7 +377,7 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
ret += r;
data = (const uint8_t*) data + r;
- size -= r;
+ size -= (size_t) r;
}
return ret;
@@ -390,7 +399,15 @@ int pa_close(int fd) {
}
#endif
- return close(fd);
+ for (;;) {
+ int r;
+
+ if ((r = close(fd)) >= 0)
+ return r;
+
+ if (errno != EINTR)
+ return r;
+ }
}
/* Print a warning messages in case that the given signal is not
@@ -437,7 +454,7 @@ void pa_check_signal_is_blocked(int sig) {
/* The following function is based on an example from the GNU libc
* documentation. This function is similar to GNU's asprintf(). */
char *pa_sprintf_malloc(const char *format, ...) {
- int size = 100;
+ size_t size = 100;
char *c = NULL;
pa_assert(format);
@@ -454,11 +471,11 @@ char *pa_sprintf_malloc(const char *format, ...) {
c[size-1] = 0;
- if (r > -1 && r < size)
+ if (r > -1 && (size_t) r < size)
return c;
if (r > -1) /* glibc 2.1 */
- size = r+1;
+ size = (size_t) r+1;
else /* glibc 2.0 */
size *= 2;
}
@@ -467,7 +484,7 @@ char *pa_sprintf_malloc(const char *format, ...) {
/* Same as the previous function, but use a va_list instead of an
* ellipsis */
char *pa_vsprintf_malloc(const char *format, va_list ap) {
- int size = 100;
+ size_t size = 100;
char *c = NULL;
pa_assert(format);
@@ -484,11 +501,11 @@ char *pa_vsprintf_malloc(const char *format, va_list ap) {
c[size-1] = 0;
- if (r > -1 && r < size)
+ if (r > -1 && (size_t) r < size)
return c;
if (r > -1) /* glibc 2.1 */
- size = r+1;
+ size = (size_t) r+1;
else /* glibc 2.0 */
size *= 2;
}
@@ -546,6 +563,8 @@ int pa_make_realtime(int rtprio) {
pa_log_info("Successfully enabled SCHED_FIFO scheduling for thread, with priority %i.", sp.sched_priority);
return 0;
#else
+
+ errno = ENOTSUP;
return -1;
#endif
}
@@ -653,6 +672,7 @@ int pa_raise_priority(int nice_level) {
if (nice_level < 0) {
if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
pa_log_warn("SetPriorityClass() failed: 0x%08X", GetLastError());
+ errno = EPERM;
return .-1;
} else
pa_log_info("Successfully gained high priority class.");
@@ -679,15 +699,55 @@ void pa_reset_priority(void) {
#endif
}
+static int match(const char *expr, const char *v) {
+ int k;
+ regex_t re;
+ int r;
+
+ if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ((k = regexec(&re, v, 0, NULL, 0)) == 0)
+ r = 1;
+ else if (k == REG_NOMATCH)
+ r = 0;
+ else
+ r = -1;
+
+ regfree(&re);
+
+ if (r < 0)
+ errno = EINVAL;
+
+ return r;
+}
+
/* Try to parse a boolean string value.*/
int pa_parse_boolean(const char *v) {
+ const char *expr;
+ int r;
pa_assert(v);
+ /* First we check language independant */
if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
return 1;
else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
return 0;
+ /* And then we check language dependant */
+ if ((expr = nl_langinfo(YESEXPR)))
+ if (expr[0])
+ if ((r = match(expr, v)) > 0)
+ return 1;
+
+ if ((expr = nl_langinfo(NOEXPR)))
+ if (expr[0])
+ if ((r = match(expr, v)) > 0)
+ return 0;
+
+ errno = EINVAL;
return -1;
}
@@ -875,11 +935,18 @@ static int is_group(gid_t gid, const char *name) {
#else
n = -1;
#endif
- if (n < 0) n = 512;
- data = pa_xmalloc(n);
+ if (n < 0)
+ n = 512;
+
+ data = pa_xmalloc((size_t) n);
+
+ errno = 0;
+ if (getgrgid_r(gid, &group, data, (size_t) n, &result) < 0 || !result) {
+ pa_log("getgrgid_r(%u): %s", (unsigned) gid, pa_cstrerror(errno));
+
+ if (!errno)
+ errno = ENOENT;
- if (getgrgid_r(gid, &group, data, n, &result) < 0 || !result) {
- pa_log("getgrgid_r(%u): %s", (unsigned)gid, pa_cstrerror(errno));
goto finish;
}
@@ -890,8 +957,14 @@ finish:
#else
/* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not
* support getgrgid_r. */
+
+ errno = 0;
if ((result = getgrgid(gid)) == NULL) {
pa_log("getgrgid(%u): %s", gid, pa_cstrerror(errno));
+
+ if (!errno)
+ errno = ENOENT;
+
goto finish;
}
@@ -906,27 +979,32 @@ finish:
/* Check the current user is member of the specified group */
int pa_own_uid_in_group(const char *name, gid_t *gid) {
GETGROUPS_T *gids, tgid;
- int n = sysconf(_SC_NGROUPS_MAX);
- int r = -1, i;
+ long n = sysconf(_SC_NGROUPS_MAX);
+ int r = -1, i, k;
pa_assert(n > 0);
- gids = pa_xmalloc(sizeof(GETGROUPS_T)*n);
+ gids = pa_xmalloc(sizeof(GETGROUPS_T) * (size_t) n);
- if ((n = getgroups(n, gids)) < 0) {
+ if ((n = getgroups((int) n, gids)) < 0) {
pa_log("getgroups(): %s", pa_cstrerror(errno));
goto finish;
}
for (i = 0; i < n; i++) {
- if (is_group(gids[i], name) > 0) {
+
+ if ((k = is_group(gids[i], name)) < 0)
+ goto finish;
+ else if (k > 0) {
*gid = gids[i];
r = 1;
goto finish;
}
}
- if (is_group(tgid = getgid(), name) > 0) {
+ if ((k = is_group(tgid = getgid(), name)) < 0)
+ goto finish;
+ else if (k > 0) {
*gid = tgid;
r = 1;
goto finish;
@@ -949,18 +1027,25 @@ int pa_uid_in_group(uid_t uid, const char *name) {
int r = -1;
g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
- g_buf = pa_xmalloc(g_n);
+ g_buf = pa_xmalloc((size_t) g_n);
p_n = sysconf(_SC_GETPW_R_SIZE_MAX);
- p_buf = pa_xmalloc(p_n);
+ p_buf = pa_xmalloc((size_t) p_n);
+
+ errno = 0;
+ if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
+
+ if (!errno)
+ errno = ENOENT;
- if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
goto finish;
+ }
r = 0;
for (i = gr->gr_mem; *i; i++) {
struct passwd pwbuf, *pw;
+ errno = 0;
if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw)
continue;
@@ -985,10 +1070,16 @@ gid_t pa_get_gid_of_group(const char *name) {
struct group grbuf, *gr;
g_n = sysconf(_SC_GETGR_R_SIZE_MAX);
- g_buf = pa_xmalloc(g_n);
+ g_buf = pa_xmalloc((size_t) g_n);
+
+ errno = 0;
+ if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) {
+
+ if (!errno)
+ errno = ENOENT;
- if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr)
goto finish;
+ }
ret = gr->gr_gid;
@@ -1014,19 +1105,23 @@ int pa_check_in_group(gid_t g) {
#else /* HAVE_GRP_H */
int pa_own_uid_in_group(const char *name, gid_t *gid) {
+ errno = ENOSUP;
return -1;
}
int pa_uid_in_group(uid_t uid, const char *name) {
+ errno = ENOSUP;
return -1;
}
gid_t pa_get_gid_of_group(const char *name) {
+ errno = ENOSUP;
return (gid_t) -1;
}
int pa_check_in_group(gid_t g) {
+ errno = ENOSUP;
return -1;
}
@@ -1040,7 +1135,7 @@ int pa_lock_fd(int fd, int b) {
/* Try a R/W lock first */
- flock.l_type = b ? F_WRLCK : F_UNLCK;
+ flock.l_type = (short) (b ? F_WRLCK : F_UNLCK);
flock.l_whence = SEEK_SET;
flock.l_start = 0;
flock.l_len = 0;
@@ -1067,6 +1162,8 @@ int pa_lock_fd(int fd, int b) {
return 0;
pa_log("%slock failed: 0x%08X", !b ? "un" : "", GetLastError());
+
+ /* FIXME: Needs to set errno! */
#endif
return -1;
@@ -1133,8 +1230,11 @@ int pa_lock_lockfile(const char *fn) {
fail:
- if (fd >= 0)
+ if (fd >= 0) {
+ int saved_errno = errno;
pa_close(fd);
+ errno = saved_errno;
+ }
return -1;
}
@@ -1180,6 +1280,7 @@ static char *get_pulse_home(void) {
if (st.st_uid != getuid()) {
pa_log_error("Home directory %s not ours.", h);
+ errno = EACCES;
return NULL;
}
@@ -1199,7 +1300,7 @@ char *pa_get_state_dir(void) {
/* If PULSE_STATE_PATH and PULSE_RUNTIME_PATH point to the same
* dir then this will break. */
- if (pa_make_secure_dir(d, 0700, (pid_t) -1, (pid_t) -1) < 0) {
+ if (pa_make_secure_dir(d, 0700U, (uid_t) -1, (gid_t) -1) < 0) {
pa_log_error("Failed to create secure directory: %s", pa_cstrerror(errno));
pa_xfree(d);
return NULL;
@@ -1214,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;
+
+ 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[sizeof(fn)-1] = 0;
+ 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;
}
}
@@ -1269,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,
@@ -1277,12 +1391,11 @@ 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() ? 0755 : 0700;
+ if ((d = getenv("PULSE_RUNTIME_PATH"))) {
- if (pa_make_secure_dir(d, m, (pid_t) -1, (pid_t) -1) < 0) {
+ 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;
}
@@ -1293,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;
@@ -1332,6 +1450,7 @@ char *pa_get_runtime_dir(void) {
/* Make sure that this actually makes sense */
if (!pa_is_path_absolute(p)) {
pa_log_error("Path %s in link %s is not absolute.", p, k);
+ errno = ENOENT;
goto fail;
}
@@ -1423,6 +1542,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
+ /* FIXME: Needs to set errno! */
return NULL;
fn = buf;
#endif
@@ -1453,6 +1573,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
+ /* FIXME: Needs to set errno! */
pa_xfree(lfn);
return NULL;
}
@@ -1481,6 +1602,7 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
+ /* FIXME: Needs to set errno! */
return NULL;
global = buf;
#endif
@@ -1492,9 +1614,9 @@ FILE *pa_open_config_file(const char *global, const char *local, const char *env
return f;
}
- } else
- errno = ENOENT;
+ }
+ errno = ENOENT;
return NULL;
}
@@ -1511,6 +1633,7 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX))
+ /* FIXME: Needs to set errno! */
return NULL;
fn = buf;
#endif
@@ -1536,6 +1659,7 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) {
+ /* FIXME: Needs to set errno! */
pa_xfree(lfn);
return NULL;
}
@@ -1560,14 +1684,16 @@ char *pa_find_config_file(const char *global, const char *local, const char *env
if (global) {
#ifdef OS_IS_WIN32
if (!ExpandEnvironmentStrings(global, buf, PATH_MAX))
+ /* FIXME: Needs to set errno! */
return NULL;
global = buf;
#endif
if (access(global, R_OK) == 0)
return pa_xstrdup(global);
- } else
- errno = ENOENT;
+ }
+
+ errno = ENOENT;
return NULL;
}
@@ -1604,6 +1730,7 @@ static int hexc(char c) {
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
+ errno = EINVAL;
return -1;
}
@@ -1742,11 +1869,16 @@ int pa_atoi(const char *s, int32_t *ret_i) {
errno = 0;
l = strtol(s, &x, 0);
- if (!x || *x || errno != 0)
+ if (!x || *x || errno) {
+ if (!errno)
+ errno = EINVAL;
return -1;
+ }
- if ((int32_t) l != l)
+ if ((int32_t) l != l) {
+ errno = ERANGE;
return -1;
+ }
*ret_i = (int32_t) l;
@@ -1764,11 +1896,16 @@ int pa_atou(const char *s, uint32_t *ret_u) {
errno = 0;
l = strtoul(s, &x, 0);
- if (!x || *x || errno != 0)
+ if (!x || *x || errno) {
+ if (!errno)
+ errno = EINVAL;
return -1;
+ }
- if ((uint32_t) l != l)
+ if ((uint32_t) l != l) {
+ errno = ERANGE;
return -1;
+ }
*ret_u = (uint32_t) l;
@@ -1786,7 +1923,6 @@ static void c_locale_destroy(void) {
int pa_atod(const char *s, double *ret_d) {
char *x = NULL;
double f;
- int r = 0;
pa_assert(s);
pa_assert(ret_d);
@@ -1812,17 +1948,20 @@ int pa_atod(const char *s, double *ret_d) {
f = strtod(s, &x);
}
- if (!x || *x || errno != 0)
- r = -1;
- else
- *ret_d = f;
+ if (!x || *x || errno) {
+ if (!errno)
+ errno = EINVAL;
+ return -1;
+ }
- return r;
+ *ret_d = f;
+
+ return 0;
}
/* Same as snprintf, but guarantees NUL-termination on every platform */
-int pa_snprintf(char *str, size_t size, const char *format, ...) {
- int ret;
+size_t pa_snprintf(char *str, size_t size, const char *format, ...) {
+ size_t ret;
va_list ap;
pa_assert(str);
@@ -1837,7 +1976,7 @@ int pa_snprintf(char *str, size_t size, const char *format, ...) {
}
/* Same as vsnprintf, but guarantees NUL-termination on every platform */
-int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
+size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
int ret;
pa_assert(str);
@@ -1849,9 +1988,12 @@ int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
str[size-1] = 0;
if (ret < 0)
- ret = strlen(str);
+ return strlen(str);
- return PA_MIN((int) size-1, ret);
+ if ((size_t) ret > size-1)
+ return size-1;
+
+ return (size_t) ret;
}
/* Truncate the specified string, but guarantee that the string
@@ -1875,7 +2017,7 @@ char *pa_getcwd(void) {
size_t l = 128;
for (;;) {
- char *p = pa_xnew(char, l);
+ char *p = pa_xmalloc(l);
if (getcwd(p, l))
return p;
@@ -1900,7 +2042,7 @@ void *pa_will_need(const void *p, size_t l) {
pa_assert(l > 0);
a = PA_PAGE_ALIGN_PTR(p);
- size = (const uint8_t*) p + l - (const uint8_t*) a;
+ size = (size_t) ((const uint8_t*) p + l - (const uint8_t*) a);
#ifdef HAVE_POSIX_MADVISE
if ((r = posix_madvise((void*) a, size, POSIX_MADV_WILLNEED)) == 0) {
@@ -1921,10 +2063,11 @@ void *pa_will_need(const void *p, size_t l) {
if (rlim.rlim_cur < PA_PAGE_SIZE) {
pa_log_debug("posix_madvise() failed (or doesn't exist), resource limits don't allow mlock(), can't page in data: %s", pa_cstrerror(r));
+ errno = EPERM;
return (void*) p;
}
- bs = PA_PAGE_ALIGN(rlim.rlim_cur);
+ bs = PA_PAGE_ALIGN((size_t) rlim.rlim_cur);
#else
bs = PA_PAGE_SIZE*4;
#endif
@@ -1976,7 +2119,7 @@ char *pa_readlink(const char *p) {
char *c;
ssize_t n;
- c = pa_xnew(char, l);
+ c = pa_xmalloc(l);
if ((n = readlink(p, c, l-1)) < 0) {
pa_xfree(c);
@@ -1995,8 +2138,8 @@ char *pa_readlink(const char *p) {
int pa_close_all(int except_fd, ...) {
va_list ap;
- int n = 0, i, r;
- int *p;
+ unsigned n = 0, i;
+ int r, *p;
va_start(ap, except_fd);
@@ -2123,8 +2266,8 @@ int pa_close_allv(const int except_fds[]) {
int pa_unblock_sigs(int except, ...) {
va_list ap;
- int n = 0, i, r;
- int *p;
+ unsigned n = 0, i;
+ int r, *p;
va_start(ap, except);
@@ -2172,8 +2315,8 @@ int pa_unblock_sigsv(const int except[]) {
int pa_reset_sigs(int except, ...) {
va_list ap;
- int n = 0, i, r;
- int *p;
+ unsigned n = 0, i;
+ int *p, r;
va_start(ap, except);
@@ -2208,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) {
@@ -2266,36 +2409,48 @@ char *pa_machine_id(void) {
FILE *f;
size_t l;
+ /* The returned value is supposed be some kind of ascii identifier
+ * that is unique and stable across reboots. */
+
+ /* First we try the D-Bus UUID, which is the best option we have,
+ * since it fits perfectly our needs and is not as volatile as the
+ * hostname which might be set from dhcp. */
+
if ((f = fopen(PA_MACHINE_ID, "r"))) {
char ln[34] = "", *r;
r = fgets(ln, sizeof(ln)-1, f);
fclose(f);
- if (r)
- return pa_xstrdup(pa_strip_nl(ln));
+ pa_strip_nl(ln);
+
+ if (ln[0])
+ return pa_xstrdup(ln);
}
- l = 100;
+ /* The we fall back to the host name. It supposed to be somewhat
+ * unique, at least in a network, but may change. */
+ l = 100;
for (;;) {
char *c;
- c = pa_xnew(char, l);
+ c = pa_xmalloc(l);
if (!pa_get_host_name(c, l)) {
- if (errno == EINVAL || errno == ENAMETOOLONG) {
+ if (errno != EINVAL && errno != ENAMETOOLONG)
+ break;
+
+ } else if (strlen(c) < l-1) {
+
+ if (*c == 0) {
pa_xfree(c);
- l *= 2;
- continue;
+ break;
}
- return NULL;
- }
-
- if (strlen(c) < l-1)
return c;
+ }
/* Hmm, the hostname is as long the space we offered the
* function, we cannot know if it fully fit in, so let's play
@@ -2304,4 +2459,31 @@ char *pa_machine_id(void) {
pa_xfree(c);
l *= 2;
}
+
+ /* If no hostname was set we use the POSIX hostid. It's usually
+ * the IPv4 address. Mit not be that stable. */
+ return pa_sprintf_malloc("%08lx", (unsigned long) gethostid);
+}
+
+char *pa_uname_string(void) {
+ struct utsname u;
+
+ pa_assert_se(uname(&u) == 0);
+
+ 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 838e4ad3..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
@@ -127,8 +131,8 @@ int pa_atoi(const char *s, int32_t *ret_i);
int pa_atou(const char *s, uint32_t *ret_u);
int pa_atod(const char *s, double *ret_d);
-int pa_snprintf(char *str, size_t size, const char *format, ...);
-int pa_vsnprintf(char *str, size_t size, const char *format, va_list ap);
+size_t pa_snprintf(char *str, size_t size, const char *format, ...);
+size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap);
char *pa_truncate_utf8(char *c, size_t l);
@@ -142,29 +146,35 @@ static inline int pa_is_power_of_two(unsigned n) {
return !(n & (n - 1));
}
-static inline unsigned pa_make_power_of_two(unsigned n) {
- unsigned j = n;
+static inline unsigned pa_ulog2(unsigned n) {
- if (pa_is_power_of_two(n))
- return n;
+ if (n <= 1)
+ return 0;
- while (j) {
- j = j >> 1;
- n = n | j;
- }
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+ return 8U * (unsigned) sizeof(unsigned) - (unsigned) __builtin_clz(n) - 1;
+#else
+{
+ unsigned r = 0;
- return n + 1;
-}
+ for (;;) {
+ n = n >> 1;
-static inline unsigned pa_ulog2(unsigned n) {
- unsigned r = 0;
+ if (!n)
+ return r;
- while (n) {
r++;
- n = n >> 1;
}
+}
+#endif
+}
+
+static inline unsigned pa_make_power_of_two(unsigned n) {
+
+ if (pa_is_power_of_two(n))
+ return n;
- return r;
+ return 1U << (pa_ulog2(n) + 1);
}
void pa_close_pipe(int fds[2]);
@@ -185,5 +195,15 @@ pa_bool_t pa_in_system_mode(void);
#define pa_streq(a,b) (!strcmp((a),(b)))
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 5c594b02..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;
}
@@ -138,6 +138,7 @@ pa_core* pa_core_new(pa_mainloop_api *m, int shared) {
c->realtime_scheduling = FALSE;
c->realtime_priority = 5;
c->disable_remixing = FALSE;
+ c->disable_lfe_remixing = FALSE;
for (j = 0; j < PA_CORE_HOOK_MAX; j++)
pa_hook_init(&c->hooks[j], c);
@@ -200,10 +201,11 @@ static void core_free(pa_object *o) {
pa_xfree(c);
}
-static void exit_callback(pa_mainloop_api*m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
+static void exit_callback(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) {
pa_core *c = userdata;
pa_assert(c->exit_event == e);
+ pa_log_info("We are idle, quitting...");
pa_core_exit(c, TRUE, 0);
}
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index eb768418..f796fb93 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -49,6 +49,7 @@ typedef enum pa_core_hook {
PA_CORE_HOOK_SINK_UNLINK_POST,
PA_CORE_HOOK_SINK_STATE_CHANGED,
PA_CORE_HOOK_SINK_PROPLIST_CHANGED,
+ PA_CORE_HOOK_SINK_SET_VOLUME,
PA_CORE_HOOK_SOURCE_NEW,
PA_CORE_HOOK_SOURCE_FIXATE,
PA_CORE_HOOK_SOURCE_PUT,
@@ -65,6 +66,7 @@ typedef enum pa_core_hook {
PA_CORE_HOOK_SINK_INPUT_MOVE_POST,
PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED,
PA_CORE_HOOK_SINK_INPUT_PROPLIST_CHANGED,
+ PA_CORE_HOOK_SINK_INPUT_SET_VOLUME,
PA_CORE_HOOK_SOURCE_OUTPUT_NEW,
PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE,
PA_CORE_HOOK_SOURCE_OUTPUT_PUT,
@@ -124,6 +126,7 @@ struct pa_core {
pa_bool_t running_as_daemon:1;
pa_bool_t realtime_scheduling:1;
pa_bool_t disable_remixing:1;
+ pa_bool_t disable_lfe_remixing:1;
pa_resample_method_t resample_method;
int realtime_priority;
@@ -140,7 +143,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/endianmacros.h b/src/pulsecore/endianmacros.h
index 26336918..1b94de17 100644
--- a/src/pulsecore/endianmacros.h
+++ b/src/pulsecore/endianmacros.h
@@ -46,9 +46,14 @@
#endif
static inline float PA_FLOAT32_SWAP(float x) {
- uint32_t i = *(uint32_t*) &x;
- i = PA_UINT32_SWAP(i);
- return *(float*) &i;
+ union {
+ float f;
+ uint32_t u;
+ } t;
+
+ t.f = x;
+ t.u = PA_UINT32_SWAP(t.u);
+ return t.f;
}
#define PA_MAYBE_INT16_SWAP(c,x) ((c) ? PA_INT32_SWAP(x) : x)
diff --git a/src/pulsecore/envelope.c b/src/pulsecore/envelope.c
index e2691611..7f2252e9 100644
--- a/src/pulsecore/envelope.c
+++ b/src/pulsecore/envelope.c
@@ -153,11 +153,11 @@ void pa_envelope_free(pa_envelope *e) {
}
static int32_t linear_interpolate_int(pa_usec_t x1, int32_t _y1, pa_usec_t x2, int32_t y2, pa_usec_t x3) {
- return (int32_t) (_y1 + (x3 - x1) * (float) (y2 - _y1) / (float) (x2 - x1));
+ return (int32_t) ((double) _y1 + (double) (x3 - x1) * (double) (y2 - _y1) / (double) (x2 - x1));
}
static float linear_interpolate_float(pa_usec_t x1, float _y1, pa_usec_t x2, float y2, pa_usec_t x3) {
- return _y1 + (x3 - x1) * (y2 - _y1) / (x2 - x1);
+ return _y1 + ((float) x3 - (float) x1) * (y2 - _y1) / ((float) x2 - (float) x1);
}
static int32_t item_get_int(pa_envelope_item *i, pa_usec_t x) {
@@ -573,11 +573,11 @@ static float linear_get_float(pa_envelope *e, int v) {
if (!e->points[v].cached_valid) {
e->points[v].cached_dy_dx =
(e->points[v].y.f[e->points[v].n_current+1] - e->points[v].y.f[e->points[v].n_current]) /
- (e->points[v].x[e->points[v].n_current+1] - e->points[v].x[e->points[v].n_current]);
+ ((float) e->points[v].x[e->points[v].n_current+1] - (float) e->points[v].x[e->points[v].n_current]);
e->points[v].cached_valid = TRUE;
}
- return e->points[v].y.f[e->points[v].n_current] + (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx;
+ return e->points[v].y.f[e->points[v].n_current] + (float) (e->x - e->points[v].x[e->points[v].n_current]) * e->points[v].cached_dy_dx;
}
void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
@@ -605,7 +605,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
uint8_t *t;
for (t = p; n > 0; n -= fs) {
- int16_t factor = linear_get_int(e, v);
+ int32_t factor = linear_get_int(e, v);
unsigned c;
e->x += fs;
@@ -620,13 +620,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
uint8_t *t;
for (t = p; n > 0; n -= fs) {
- int16_t factor = linear_get_int(e, v);
+ int32_t factor = linear_get_int(e, v);
unsigned c;
e->x += fs;
for (c = 0; c < e->sample_spec.channels; c++, t++) {
int16_t k = st_ulaw2linear16(*t);
- *t = (uint8_t) st_14linear2ulaw(((factor * k) / 0x10000) >> 2);
+ *t = (uint8_t) st_14linear2ulaw((int16_t) (((factor * k) / 0x10000) >> 2));
}
}
@@ -637,13 +637,13 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
uint8_t *t;
for (t = p; n > 0; n -= fs) {
- int16_t factor = linear_get_int(e, v);
+ int32_t factor = linear_get_int(e, v);
unsigned c;
e->x += fs;
for (c = 0; c < e->sample_spec.channels; c++, t++) {
int16_t k = st_alaw2linear16(*t);
- *t = (uint8_t) st_13linear2alaw(((factor * k) / 0x10000) >> 3);
+ *t = (uint8_t) st_13linear2alaw((int16_t) (((factor * k) / 0x10000) >> 3));
}
}
@@ -659,7 +659,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
e->x += fs;
for (c = 0; c < e->sample_spec.channels; c++, t++)
- *t = (factor * *t) / 0x10000;
+ *t = (int16_t) ((factor * *t) / 0x10000);
}
break;
@@ -674,7 +674,7 @@ void pa_envelope_apply(pa_envelope *e, pa_memchunk *chunk) {
e->x += fs;
for (c = 0; c < e->sample_spec.channels; c++, t++) {
- int16_t r = (factor * PA_INT16_SWAP(*t)) / 0x10000;
+ int16_t r = (int16_t) ((factor * PA_INT16_SWAP(*t)) / 0x10000);
*t = PA_INT16_SWAP(r);
}
}
diff --git a/src/pulsecore/fdsem.c b/src/pulsecore/fdsem.c
index 1531e3db..380f34f5 100644
--- a/src/pulsecore/fdsem.c
+++ b/src/pulsecore/fdsem.c
@@ -41,39 +41,15 @@
#include <pulsecore/pipe.h>
#endif
-#ifdef __linux__
-
-#if !defined(__NR_eventfd) && defined(__i386__)
-#define __NR_eventfd 323
-#endif
-
-#if !defined(__NR_eventfd) && defined(__x86_64__)
-#define __NR_eventfd 284
-#endif
-
-#if !defined(__NR_eventfd) && defined(__arm__)
-#define __NR_eventfd (__NR_SYSCALL_BASE+351)
-#endif
-
-#if !defined(SYS_eventfd) && defined(__NR_eventfd)
-#define SYS_eventfd __NR_eventfd
-#endif
-
-#ifdef SYS_eventfd
-#define HAVE_EVENTFD
-
-static inline long eventfd(unsigned count) {
- return syscall(SYS_eventfd, count);
-}
-
-#endif
+#ifdef HAVE_SYS_EVENTFD_H
+#include <sys/eventfd.h>
#endif
#include "fdsem.h"
struct pa_fdsem {
int fds[2];
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
int efd;
#endif
@@ -85,8 +61,8 @@ pa_fdsem *pa_fdsem_new(void) {
f = pa_xmalloc(PA_ALIGN(sizeof(pa_fdsem)) + PA_ALIGN(sizeof(pa_fdsem_data)));
-#ifdef HAVE_EVENTFD
- if ((f->efd = eventfd(0)) >= 0) {
+#ifdef HAVE_SYS_EVENTFD_H
+ if ((f->efd = eventfd(0, 0)) >= 0) {
pa_make_fd_cloexec(f->efd);
f->fds[0] = f->fds[1] = -1;
} else
@@ -116,7 +92,7 @@ pa_fdsem *pa_fdsem_open_shm(pa_fdsem_data *data, int event_fd) {
pa_assert(data);
pa_assert(event_fd >= 0);
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
f = pa_xnew(pa_fdsem, 1);
f->efd = event_fd;
@@ -134,11 +110,11 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {
pa_assert(data);
pa_assert(event_fd);
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
f = pa_xnew(pa_fdsem, 1);
- if ((f->efd = eventfd(0)) < 0) {
+ if ((f->efd = eventfd(0, 0)) < 0) {
pa_xfree(f);
return NULL;
}
@@ -159,7 +135,7 @@ pa_fdsem *pa_fdsem_new_shm(pa_fdsem_data *data, int* event_fd) {
void pa_fdsem_free(pa_fdsem *f) {
pa_assert(f);
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
if (f->efd >= 0)
pa_close(f->efd);
#endif
@@ -178,7 +154,7 @@ static void flush(pa_fdsem *f) {
do {
char x[10];
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
if (f->efd >= 0) {
uint64_t u;
@@ -195,7 +171,7 @@ static void flush(pa_fdsem *f) {
continue;
}
- } while (pa_atomic_sub(&f->data->in_pipe, r) > r);
+ } while (pa_atomic_sub(&f->data->in_pipe, (int) r) > (int) r);
}
void pa_fdsem_post(pa_fdsem *f) {
@@ -211,7 +187,7 @@ void pa_fdsem_post(pa_fdsem *f) {
for (;;) {
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
if (f->efd >= 0) {
uint64_t u = 1;
@@ -247,7 +223,7 @@ void pa_fdsem_wait(pa_fdsem *f) {
char x[10];
ssize_t r;
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
if (f->efd >= 0) {
uint64_t u;
@@ -265,7 +241,7 @@ void pa_fdsem_wait(pa_fdsem *f) {
continue;
}
- pa_atomic_sub(&f->data->in_pipe, r);
+ pa_atomic_sub(&f->data->in_pipe, (int) r);
}
pa_assert_se(pa_atomic_dec(&f->data->waiting) >= 1);
@@ -285,7 +261,7 @@ int pa_fdsem_try(pa_fdsem *f) {
int pa_fdsem_get(pa_fdsem *f) {
pa_assert(f);
-#ifdef HAVE_EVENTFD
+#ifdef HAVE_SYS_EVENTFD_H
if (f->efd >= 0)
return f->efd;
#endif
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 fb4497b8..24a28db7 100644
--- a/src/pulsecore/idxset.c
+++ b/src/pulsecore/idxset.c
@@ -66,7 +66,7 @@ unsigned pa_idxset_string_hash_func(const void *p) {
const char *c;
for (c = p; *c; c++)
- hash = 31 * hash + *c;
+ hash = 31 * hash + (unsigned) *c;
return hash;
}
@@ -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) {
@@ -318,8 +318,7 @@ void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) {
hash = *idx % NBUCKETS;
- if (!(e = index_scan(s, hash, *idx)))
- return NULL;
+ e = index_scan(s, hash, *idx);
if (e && e->iterate_next)
e = e->iterate_next;
diff --git a/src/pulsecore/ioline.c b/src/pulsecore/ioline.c
index 90afaafd..88174c05 100644
--- a/src/pulsecore/ioline.c
+++ b/src/pulsecore/ioline.c
@@ -164,7 +164,7 @@ void pa_ioline_puts(pa_ioline *l, const char *c) {
/* In case the allocated buffer is too small, enlarge it. */
if (l->wbuf_valid_length + len > l->wbuf_length) {
size_t n = l->wbuf_valid_length+len;
- char *new = pa_xnew(char, n);
+ char *new = pa_xnew(char, (unsigned) n);
if (l->wbuf) {
memcpy(new, l->wbuf+l->wbuf_index, l->wbuf_valid_length);
@@ -285,7 +285,7 @@ static int do_read(pa_ioline *l) {
memmove(l->rbuf, l->rbuf+l->rbuf_index, l->rbuf_valid_length);
} else {
/* Enlarge the buffer */
- char *new = pa_xnew(char, n);
+ char *new = pa_xnew(char, (unsigned) n);
if (l->rbuf_valid_length)
memcpy(new, l->rbuf+l->rbuf_index, l->rbuf_valid_length);
pa_xfree(l->rbuf);
@@ -315,10 +315,10 @@ static int do_read(pa_ioline *l) {
return -1;
}
- l->rbuf_valid_length += r;
+ l->rbuf_valid_length += (size_t) r;
/* Look if a line has been terminated in the newly read data */
- scan_for_lines(l, l->rbuf_valid_length - r);
+ scan_for_lines(l, l->rbuf_valid_length - (size_t) r);
}
return 0;
@@ -346,8 +346,8 @@ static int do_write(pa_ioline *l) {
return -1;
}
- l->wbuf_index += r;
- l->wbuf_valid_length -= r;
+ l->wbuf_index += (size_t) r;
+ l->wbuf_valid_length -= (size_t) r;
/* A shortcut for the next time */
if (l->wbuf_valid_length == 0)
diff --git a/src/pulsecore/ipacl.c b/src/pulsecore/ipacl.c
index 7b5f865b..6d5080fb 100644
--- a/src/pulsecore/ipacl.c
+++ b/src/pulsecore/ipacl.c
@@ -122,7 +122,7 @@ pa_ip_acl* pa_ip_acl_new(const char *s) {
if (e.bits < 128) {
int t = 0, i;
- for (i = 0, bits = e.bits; i < 16; i++) {
+ for (i = 0, bits = (uint32_t) e.bits; i < 16; i++) {
if (bits >= 8)
bits -= 8;
diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c
new file mode 100644
index 00000000..d36b669e
--- /dev/null
+++ b/src/pulsecore/lock-autospawn.c
@@ -0,0 +1,330 @@
+/***
+ 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 <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/poll.h>
+#include <signal.h>
+#include <pthread.h>
+
+#include <pulse/i18n.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/mutex.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/core-util.h>
+
+#include "lock-autospawn.h"
+
+/* So, why do we have this complex code here with threads and pipes
+ * and stuff? For two reasons: POSIX file locks are per-process, not
+ * per-file descriptor. That means that two contexts within the same
+ * process that try to create the autospawn lock might end up assuming
+ * they both managed to lock the file. And then, POSIX locking
+ * operations are synchronous. If two contexts run from the same event
+ * loop it must be made sure that they do not block each other, but
+ * that the locking operation can happen asynchronously. */
+
+#define AUTOSPAWN_LOCK "autospawn.lock"
+
+static pa_mutex *mutex;
+
+static unsigned n_ref = 0;
+static int lock_fd = -1;
+static pa_mutex *lock_fd_mutex = NULL;
+static pa_bool_t taken = FALSE;
+static pa_thread *thread;
+static int pipe_fd[2] = { -1, -1 };
+
+static void destroy_mutex(void) PA_GCC_DESTRUCTOR;
+
+static int ref(void) {
+
+ if (n_ref > 0) {
+
+ pa_assert(pipe_fd[0] >= 0);
+ pa_assert(pipe_fd[1] >= 0);
+
+ n_ref++;
+
+ return 0;
+ }
+
+ pa_assert(lock_fd < 0);
+ pa_assert(!lock_fd_mutex);
+ pa_assert(!taken);
+ pa_assert(!thread);
+ pa_assert(pipe_fd[0] < 0);
+ pa_assert(pipe_fd[1] < 0);
+
+ if (pipe(pipe_fd) < 0)
+ return -1;
+
+ lock_fd_mutex = pa_mutex_new(FALSE, FALSE);
+
+ pa_make_fd_cloexec(pipe_fd[0]);
+ pa_make_fd_cloexec(pipe_fd[1]);
+
+ pa_make_fd_nonblock(pipe_fd[1]);
+ pa_make_fd_nonblock(pipe_fd[0]);
+
+ n_ref = 1;
+ return 0;
+}
+
+static void unref(pa_bool_t after_fork) {
+
+ pa_assert(n_ref > 0);
+ pa_assert(pipe_fd[0] >= 0);
+ pa_assert(pipe_fd[1] >= 0);
+ pa_assert(lock_fd_mutex);
+
+ n_ref--;
+
+ if (n_ref > 0)
+ return;
+
+ pa_assert(!taken);
+
+ if (thread) {
+ pa_thread_free(thread);
+ thread = NULL;
+ }
+
+ pa_mutex_lock(lock_fd_mutex);
+ if (lock_fd >= 0) {
+
+ if (after_fork)
+ pa_close(lock_fd);
+ else {
+ char *lf;
+
+ if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK)))
+ pa_log_warn(_("Cannot access autospawn lock."));
+
+ pa_unlock_lockfile(lf, lock_fd);
+ pa_xfree(lf);
+
+ lock_fd = -1;
+ }
+ }
+ pa_mutex_unlock(lock_fd_mutex);
+
+ pa_mutex_free(lock_fd_mutex);
+ lock_fd_mutex = NULL;
+
+ pa_close(pipe_fd[0]);
+ pa_close(pipe_fd[1]);
+ pipe_fd[0] = pipe_fd[1] = -1;
+}
+
+static void ping(void) {
+ ssize_t s;
+
+ pa_assert(pipe_fd[1] >= 0);
+
+ for (;;) {
+ char x = 'x';
+
+ if ((s = write(pipe_fd[1], &x, 1)) == 1)
+ break;
+
+ pa_assert(s < 0);
+
+ if (errno == EAGAIN)
+ break;
+
+ pa_assert(errno == EINTR);
+ }
+}
+
+static void wait_for_ping(void) {
+ ssize_t s;
+ char x;
+ struct pollfd pfd;
+ int k;
+
+ pa_assert(pipe_fd[0] >= 0);
+
+ memset(&pfd, 0, sizeof(pfd));
+ pfd.fd = pipe_fd[0];
+ pfd.events = POLLIN;
+
+ if ((k = poll(&pfd, 1, -1)) != 1) {
+ pa_assert(k < 0);
+ pa_assert(errno == EINTR);
+ } else if ((s = read(pipe_fd[0], &x, 1)) != 1) {
+ pa_assert(s < 0);
+ pa_assert(errno == EAGAIN);
+ }
+}
+
+static void empty_pipe(void) {
+ char x[16];
+ ssize_t s;
+
+ pa_assert(pipe_fd[0] >= 0);
+
+ if ((s = read(pipe_fd[0], &x, sizeof(x))) < 1) {
+ pa_assert(s < 0);
+ pa_assert(errno == EAGAIN);
+ }
+}
+
+static void thread_func(void *u) {
+ int fd;
+ char *lf;
+ sigset_t fullset;
+
+ /* No signals in this thread please */
+ sigfillset(&fullset);
+ pthread_sigmask(SIG_BLOCK, &fullset, NULL);
+
+ if (!(lf = pa_runtime_path(AUTOSPAWN_LOCK))) {
+ pa_log_warn(_("Cannot access autospawn lock."));
+ goto finish;
+ }
+
+ if ((fd = pa_lock_lockfile(lf)) < 0)
+ goto finish;
+
+ pa_mutex_lock(lock_fd_mutex);
+ pa_assert(lock_fd < 0);
+ lock_fd = fd;
+ pa_mutex_unlock(lock_fd_mutex);
+
+finish:
+ pa_xfree(lf);
+
+ ping();
+}
+
+static int start_thread(void) {
+
+ if (!thread)
+ if (!(thread = pa_thread_new(thread_func, NULL)))
+ return -1;
+
+ return 0;
+}
+
+static void create_mutex(void) {
+ PA_ONCE_BEGIN {
+ mutex = pa_mutex_new(FALSE, FALSE);
+ } PA_ONCE_END;
+}
+
+static void destroy_mutex(void) {
+
+ if (mutex)
+ pa_mutex_free(mutex);
+}
+
+
+int pa_autospawn_lock_init(void) {
+ int ret = -1;
+
+ create_mutex();
+ pa_mutex_lock(mutex);
+
+ if (ref() < 0)
+ ret = -1;
+ else
+ ret = pipe_fd[0];
+
+ pa_mutex_unlock(mutex);
+
+ return ret;
+}
+
+int pa_autospawn_lock_acquire(pa_bool_t block) {
+ int ret = -1;
+
+ create_mutex();
+ pa_mutex_lock(mutex);
+ pa_assert(n_ref >= 1);
+
+ pa_mutex_lock(lock_fd_mutex);
+
+ for (;;) {
+
+ empty_pipe();
+
+ if (lock_fd >= 0 && !taken) {
+ taken = TRUE;
+ ret = 1;
+ break;
+ }
+
+ if (lock_fd < 0)
+ if (start_thread() < 0)
+ break;
+
+ if (!block) {
+ ret = 0;
+ break;
+ }
+
+ pa_mutex_unlock(lock_fd_mutex);
+ pa_mutex_unlock(mutex);
+
+ wait_for_ping();
+
+ pa_mutex_lock(mutex);
+ pa_mutex_lock(lock_fd_mutex);
+ }
+
+ pa_mutex_unlock(lock_fd_mutex);
+
+ pa_mutex_unlock(mutex);
+
+ return ret;
+}
+
+void pa_autospawn_lock_release(void) {
+
+ create_mutex();
+ pa_mutex_lock(mutex);
+ pa_assert(n_ref >= 1);
+
+ pa_assert(taken);
+ taken = FALSE;
+
+ ping();
+
+ pa_mutex_unlock(mutex);
+}
+
+void pa_autospawn_lock_done(pa_bool_t after_fork) {
+
+ create_mutex();
+ pa_mutex_lock(mutex);
+ pa_assert(n_ref >= 1);
+
+ unref(after_fork);
+
+ pa_mutex_unlock(mutex);
+}
diff --git a/src/pulsecore/lock-autospawn.h b/src/pulsecore/lock-autospawn.h
new file mode 100644
index 00000000..c04c4bd1
--- /dev/null
+++ b/src/pulsecore/lock-autospawn.h
@@ -0,0 +1,32 @@
+#ifndef foopulselockautospawnhfoo
+#define foopulselockautospawnhfoo
+
+/***
+ 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 <pulsecore/macro.h>
+
+int pa_autospawn_lock_init(void);
+int pa_autospawn_lock_acquire(pa_bool_t block);
+void pa_autospawn_lock_release(void);
+void pa_autospawn_lock_done(pa_bool_t after_fork);
+
+#endif
diff --git a/src/pulsecore/log.c b/src/pulsecore/log.c
index 5eda4f65..adf2f112 100644
--- a/src/pulsecore/log.c
+++ b/src/pulsecore/log.c
@@ -30,6 +30,10 @@
#include <string.h>
#include <errno.h>
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
@@ -37,19 +41,27 @@
#include <pulse/utf8.h>
#include <pulse/xmalloc.h>
#include <pulse/util.h>
+#include <pulse/timeval.h>
#include <pulsecore/macro.h>
#include <pulsecore/core-util.h>
+#include <pulsecore/rtclock.h>
+#include <pulsecore/once.h>
#include "log.h"
#define ENV_LOGLEVEL "PULSE_LOG"
#define ENV_LOGMETA "PULSE_LOG_META"
+#define ENV_LOGTIME "PULSE_LOG_TIME"
+#define ENV_LOGBACKTRACE "PULSE_LOG_BACKTRACE"
static char *log_ident = NULL, *log_ident_local = NULL;
static pa_log_target_t log_target = PA_LOG_STDERR;
-static void (*user_log_func)(pa_log_level_t l, const char *s) = NULL;
-static pa_log_level_t maximal_level = PA_LOG_NOTICE;
+static pa_log_func_t user_log_func = NULL;
+static pa_log_level_t maximal_level = PA_LOG_ERROR;
+static unsigned show_backtrace = 0;
+static pa_bool_t show_meta = FALSE;
+static pa_bool_t show_time = FALSE;
#ifdef HAVE_SYSLOG_H
static const int level_to_syslog[] = {
@@ -81,6 +93,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);
}
@@ -91,13 +106,81 @@ void pa_log_set_maximal_level(pa_log_level_t l) {
maximal_level = l;
}
-void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t l, const char*s)) {
+void pa_log_set_target(pa_log_target_t t, pa_log_func_t func) {
pa_assert(t == PA_LOG_USER || !func);
log_target = t;
user_log_func = func;
}
+void pa_log_set_show_meta(pa_bool_t b) {
+ show_meta = b;
+}
+
+void pa_log_set_show_time(pa_bool_t b) {
+ show_time = b;
+}
+
+void pa_log_set_show_backtrace(unsigned nlevels) {
+ show_backtrace = nlevels;
+}
+
+#ifdef HAVE_EXECINFO_H
+
+static char* get_backtrace(unsigned show_nframes) {
+ void* trace[32];
+ int n_frames;
+ char **symbols, *e, *r;
+ unsigned j, n;
+ size_t a;
+
+ if (show_nframes <= 0)
+ return NULL;
+
+ n_frames = backtrace(trace, PA_ELEMENTSOF(trace));
+
+ if (n_frames <= 0)
+ return NULL;
+
+ symbols = backtrace_symbols(trace, n_frames);
+
+ if (!symbols)
+ return NULL;
+
+ n = PA_MIN((unsigned) n_frames, show_nframes);
+
+ a = 4;
+
+ for (j = 0; j < n; j++) {
+ if (j > 0)
+ a += 2;
+ a += strlen(symbols[j]);
+ }
+
+ r = pa_xnew(char, a);
+
+ strcpy(r, " (");
+ e = r + 2;
+
+ for (j = 0; j < n; j++) {
+ if (j > 0) {
+ strcpy(e, "<<");
+ e += 2;
+ }
+
+ strcpy(e, symbols[j]);
+ e += strlen(symbols[j]);
+ }
+
+ strcpy(e, ")");
+
+ free(symbols);
+
+ return r;
+}
+
+#endif
+
void pa_log_levelv_meta(
pa_log_level_t level,
const char*file,
@@ -109,31 +192,82 @@ void pa_log_levelv_meta(
const char *e;
char *t, *n;
int saved_errno = errno;
+ char *bt = NULL;
+ pa_log_level_t ml;
+#ifdef HAVE_EXECINFO_H
+ unsigned show_bt;
+#endif
/* We don't use dynamic memory allocation here to minimize the hit
* in RT threads */
- char text[1024], location[128];
+ char text[4096], location[128], timestamp[32];
pa_assert(level < PA_LOG_LEVEL_MAX);
pa_assert(format);
- if ((e = getenv(ENV_LOGLEVEL)))
- maximal_level = atoi(e);
+ ml = maximal_level;
- if (level > maximal_level) {
+ if (PA_UNLIKELY((e = getenv(ENV_LOGLEVEL)))) {
+ pa_log_level_t eml = (pa_log_level_t) atoi(e);
+
+ if (eml > ml)
+ ml = eml;
+ }
+
+ if (PA_LIKELY(level > ml)) {
errno = saved_errno;
return;
}
pa_vsnprintf(text, sizeof(text), format, ap);
- if (getenv(ENV_LOGMETA) && file && line > 0 && func)
+ if ((show_meta || getenv(ENV_LOGMETA)) && file && line > 0 && func)
pa_snprintf(location, sizeof(location), "[%s:%i %s()] ", file, line, func);
else if (file)
pa_snprintf(location, sizeof(location), "%s: ", pa_path_get_filename(file));
else
location[0] = 0;
+ if (show_time || getenv(ENV_LOGTIME)) {
+ static pa_usec_t start, last;
+ pa_usec_t u, a, r;
+
+ u = pa_rtclock_usec();
+
+ PA_ONCE_BEGIN {
+ start = u;
+ last = u;
+ } PA_ONCE_END;
+
+ r = u - last;
+ a = u - start;
+
+ /* This is not thread safe, but this is a debugging tool only
+ * anyway. */
+ last = u;
+
+ pa_snprintf(timestamp, sizeof(timestamp), "(%4llu.%03llu|%4llu.%03llu) ",
+ (unsigned long long) (a / PA_USEC_PER_SEC),
+ (unsigned long long) (((a / PA_USEC_PER_MSEC)) % 1000),
+ (unsigned long long) (r / PA_USEC_PER_SEC),
+ (unsigned long long) (((r / PA_USEC_PER_MSEC)) % 1000));
+
+ } else
+ timestamp[0] = 0;
+
+#ifdef HAVE_EXECINFO_H
+ show_bt = show_backtrace;
+
+ if ((e = getenv(ENV_LOGBACKTRACE))) {
+ unsigned ebt = (unsigned) atoi(e);
+
+ if (ebt > show_bt)
+ show_bt = ebt;
+ }
+
+ bt = get_backtrace(show_bt);
+#endif
+
if (!pa_utf8_valid(text))
pa_log_level(level, __FILE__": invalid UTF-8 string following below:");
@@ -148,19 +282,22 @@ void pa_log_levelv_meta(
switch (log_target) {
case PA_LOG_STDERR: {
- const char *prefix = "", *suffix = "";
+ const char *prefix = "", *suffix = "", *grey = "";
char *local_t;
#ifndef OS_IS_WIN32
/* Yes indeed. Useless, but fun! */
if (isatty(STDERR_FILENO)) {
- if (level <= PA_LOG_ERROR) {
+ if (level <= PA_LOG_ERROR)
prefix = "\x1B[1;31m";
- suffix = "\x1B[0m";
- } else if (level <= PA_LOG_WARN) {
+ else if (level <= PA_LOG_WARN)
prefix = "\x1B[1m";
+
+ if (bt)
+ grey = "\x1B[2m";
+
+ if (grey[0] || prefix[0])
suffix = "\x1B[0m";
- }
}
#endif
@@ -168,9 +305,9 @@ void pa_log_levelv_meta(
* minimize the hit in RT threads */
local_t = pa_utf8_to_locale(t);
if (!local_t)
- fprintf(stderr, "%c: %s%s%s%s\n", level_to_char[level], location, prefix, t, suffix);
+ fprintf(stderr, "%s%c: %s%s%s%s%s%s\n", timestamp, level_to_char[level], location, prefix, t, grey, pa_strempty(bt), suffix);
else {
- fprintf(stderr, "%c: %s%s%s%s\n", level_to_char[level], location, prefix, local_t, suffix);
+ fprintf(stderr, "%s%c: %s%s%s%s%s%s\n", timestamp, level_to_char[level], location, prefix, local_t, grey, pa_strempty(bt), suffix);
pa_xfree(local_t);
}
@@ -185,9 +322,9 @@ void pa_log_levelv_meta(
local_t = pa_utf8_to_locale(t);
if (!local_t)
- syslog(level_to_syslog[level], "%s%s", location, t);
+ syslog(level_to_syslog[level], "%s%s%s%s", timestamp, location, t, pa_strempty(bt));
else {
- syslog(level_to_syslog[level], "%s%s", location, local_t);
+ syslog(level_to_syslog[level], "%s%s%s%s", timestamp, location, local_t, pa_strempty(bt));
pa_xfree(local_t);
}
@@ -199,7 +336,7 @@ void pa_log_levelv_meta(
case PA_LOG_USER: {
char x[1024];
- pa_snprintf(x, sizeof(x), "%s%s", location, t);
+ pa_snprintf(x, sizeof(x), "%s%s%s", timestamp, location, t);
user_log_func(level, x);
break;
diff --git a/src/pulsecore/log.h b/src/pulsecore/log.h
index 2047696e..3d66e903 100644
--- a/src/pulsecore/log.h
+++ b/src/pulsecore/log.h
@@ -25,6 +25,8 @@
#include <stdarg.h>
#include <stdlib.h>
+
+#include <pulsecore/macro.h>
#include <pulse/gccmacro.h>
/* A simple logging subsystem */
@@ -49,11 +51,16 @@ typedef enum pa_log_level {
/* Set an identification for the current daemon. Used when logging to syslog. */
void pa_log_set_ident(const char *p);
+typedef void (*pa_log_func_t)(pa_log_level_t t, const char*s);
+
/* Set another log target. If t is PA_LOG_USER you may specify a function that is called every log string */
-void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t t, const char*s));
+void pa_log_set_target(pa_log_target_t t, pa_log_func_t func);
-/* Minimal log level */
+/* Maximal log level */
void pa_log_set_maximal_level(pa_log_level_t l);
+void pa_log_set_show_meta(pa_bool_t b);
+void pa_log_set_show_time(pa_bool_t b);
+void pa_log_set_show_backtrace(unsigned nlevels);
void pa_log_level_meta(
pa_log_level_t level,
diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h
index fd33b7bb..f9ce949a 100644
--- a/src/pulsecore/macro.h
+++ b/src/pulsecore/macro.h
@@ -30,7 +30,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <pulsecore/log.h>
#include <pulse/gccmacro.h>
#ifndef PACKAGE
@@ -40,7 +39,7 @@
#ifndef PA_LIKELY
#ifdef __GNUC__
#define PA_LIKELY(x) (__builtin_expect(!!(x),1))
-#define PA_UNLIKELY(x) (__builtin_expect((x),0))
+#define PA_UNLIKELY(x) (__builtin_expect(!!(x),0))
#else
#define PA_LIKELY(x) (x)
#define PA_UNLIKELY(x) (x)
@@ -208,7 +207,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); \
@@ -221,4 +220,13 @@ typedef int pa_bool_t;
#endif
+#if defined(__i386__) || defined(__x86_64__)
+#define PA_DEBUG_TRAP __asm__("int $3")
+#else
+#define PA_DEBUG_TRAP raise(SIGTRAP)
+#endif
+
+/* We include this at the very last place */
+#include <pulsecore/log.h>
+
#endif
diff --git a/src/pulsecore/memblock.c b/src/pulsecore/memblock.c
index b43113d6..d9e1bf1c 100644
--- a/src/pulsecore/memblock.c
+++ b/src/pulsecore/memblock.c
@@ -31,6 +31,10 @@
#include <signal.h>
#include <errno.h>
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+#include <valgrind/memcheck.h>
+#endif
+
#include <pulse/xmalloc.h>
#include <pulse/def.h>
@@ -158,14 +162,14 @@ static void stat_add(pa_memblock*b) {
pa_assert(b->pool);
pa_atomic_inc(&b->pool->stat.n_allocated);
- pa_atomic_add(&b->pool->stat.allocated_size, b->length);
+ pa_atomic_add(&b->pool->stat.allocated_size, (int) b->length);
pa_atomic_inc(&b->pool->stat.n_accumulated);
- pa_atomic_add(&b->pool->stat.accumulated_size, b->length);
+ pa_atomic_add(&b->pool->stat.accumulated_size, (int) b->length);
if (b->type == PA_MEMBLOCK_IMPORTED) {
pa_atomic_inc(&b->pool->stat.n_imported);
- pa_atomic_add(&b->pool->stat.imported_size, b->length);
+ pa_atomic_add(&b->pool->stat.imported_size, (int) b->length);
}
pa_atomic_inc(&b->pool->stat.n_allocated_by_type[b->type]);
@@ -181,14 +185,14 @@ static void stat_remove(pa_memblock *b) {
pa_assert(pa_atomic_load(&b->pool->stat.allocated_size) >= (int) b->length);
pa_atomic_dec(&b->pool->stat.n_allocated);
- pa_atomic_sub(&b->pool->stat.allocated_size, b->length);
+ pa_atomic_sub(&b->pool->stat.allocated_size, (int) b->length);
if (b->type == PA_MEMBLOCK_IMPORTED) {
pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0);
pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length);
pa_atomic_dec(&b->pool->stat.n_imported);
- pa_atomic_sub(&b->pool->stat.imported_size, b->length);
+ pa_atomic_sub(&b->pool->stat.imported_size, (int) b->length);
}
pa_atomic_dec(&b->pool->stat.n_allocated_by_type[b->type]);
@@ -248,7 +252,7 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {
if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks)
pa_atomic_dec(&p->n_init);
else
- slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * idx));
+ slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * (size_t) idx));
if (!slot) {
pa_log_info("Pool full");
@@ -257,6 +261,12 @@ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) {
}
}
+/* #ifdef HAVE_VALGRIND_MEMCHECK_H */
+/* if (PA_UNLIKELY(pa_in_valgrind())) { */
+/* VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0); */
+/* } */
+/* #endif */
+
return slot;
}
@@ -272,7 +282,7 @@ static unsigned mempool_slot_idx(pa_mempool *p, void *ptr) {
pa_assert((uint8_t*) ptr >= (uint8_t*) p->memory.ptr);
pa_assert((uint8_t*) ptr < (uint8_t*) p->memory.ptr + p->memory.size);
- return ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size;
+ return (unsigned) ((size_t) ((uint8_t*) ptr - (uint8_t*) p->memory.ptr) / p->block_size);
}
/* No lock necessary */
@@ -519,13 +529,19 @@ static void memblock_free(pa_memblock *b) {
case PA_MEMBLOCK_POOL_EXTERNAL:
case PA_MEMBLOCK_POOL: {
struct mempool_slot *slot;
- int call_free;
+ pa_bool_t call_free;
slot = mempool_slot_by_ptr(b->pool, pa_atomic_ptr_load(&b->data));
pa_assert(slot);
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 */
@@ -647,7 +663,7 @@ static void memblock_replace_import(pa_memblock *b) {
pa_assert(pa_atomic_load(&b->pool->stat.n_imported) > 0);
pa_assert(pa_atomic_load(&b->pool->stat.imported_size) >= (int) b->length);
pa_atomic_dec(&b->pool->stat.n_imported);
- pa_atomic_sub(&b->pool->stat.imported_size, b->length);
+ pa_atomic_sub(&b->pool->stat.imported_size, (int) b->length);
seg = b->per_type.imported.segment;
pa_assert(seg);
@@ -668,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);
@@ -680,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);
@@ -754,7 +784,7 @@ void pa_mempool_vacuum(pa_mempool *p) {
;
while ((slot = pa_flist_pop(list))) {
- pa_shm_punch(&p->memory, (uint8_t*) slot - (uint8_t*) p->memory.ptr, p->block_size);
+ pa_shm_punch(&p->memory, (size_t) ((uint8_t*) slot - (uint8_t*) p->memory.ptr), p->block_size);
while (pa_flist_push(p->free_slots, slot))
;
@@ -967,7 +997,7 @@ void pa_memexport_free(pa_memexport *e) {
pa_mutex_lock(e->mutex);
while (e->used_slots)
- pa_memexport_process_release(e, e->used_slots - e->slots);
+ pa_memexport_process_release(e, (uint32_t) (e->used_slots - e->slots));
pa_mutex_unlock(e->mutex);
pa_mutex_lock(e->pool->mutex);
@@ -1006,7 +1036,7 @@ int pa_memexport_process_release(pa_memexport *e, uint32_t id) {
pa_assert(pa_atomic_load(&e->pool->stat.exported_size) >= (int) b->length);
pa_atomic_dec(&e->pool->stat.n_exported);
- pa_atomic_sub(&e->pool->stat.exported_size, b->length);
+ pa_atomic_sub(&e->pool->stat.exported_size, (int) b->length);
pa_memblock_unref(b);
@@ -1034,7 +1064,7 @@ static void memexport_revoke_blocks(pa_memexport *e, pa_memimport *i) {
slot->block->per_type.imported.segment->import != i)
continue;
- idx = slot - e->slots;
+ idx = (uint32_t) (slot - e->slots);
e->revoke_cb(e, idx, e->userdata);
pa_memexport_process_release(e, idx);
}
@@ -1095,7 +1125,7 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32
PA_LLIST_PREPEND(struct memexport_slot, e->used_slots, slot);
slot->block = b;
- *block_id = slot - e->slots;
+ *block_id = (uint32_t) (slot - e->slots);
pa_mutex_unlock(e->mutex);
/* pa_log("Got block id %u", *block_id); */
@@ -1115,13 +1145,13 @@ int pa_memexport_put(pa_memexport *e, pa_memblock *b, uint32_t *block_id, uint32
pa_assert((uint8_t*) data + b->length <= (uint8_t*) memory->ptr + memory->size);
*shm_id = memory->id;
- *offset = (uint8_t*) data - (uint8_t*) memory->ptr;
+ *offset = (size_t) ((uint8_t*) data - (uint8_t*) memory->ptr);
*size = b->length;
pa_memblock_release(b);
pa_atomic_inc(&e->pool->stat.n_exported);
- pa_atomic_add(&e->pool->stat.exported_size, b->length);
+ pa_atomic_add(&e->pool->stat.exported_size, (int) b->length);
return 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/memblockq.c b/src/pulsecore/memblockq.c
index 841b9075..265da37f 100644
--- a/src/pulsecore/memblockq.c
+++ b/src/pulsecore/memblockq.c
@@ -84,7 +84,8 @@ pa_memblockq* pa_memblockq_new(
pa_log_debug("memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu maxrewind=%lu",
(unsigned long) maxlength, (unsigned long) tlength, (unsigned long) base, (unsigned long) prebuf, (unsigned long) minreq, (unsigned long) maxrewind);
- bq->missing = bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0;
+ bq->missing = 0;
+ bq->requested = bq->maxlength = bq->tlength = bq->prebuf = bq->minreq = bq->maxrewind = 0;
bq->in_prebuf = TRUE;
pa_memblockq_set_maxlength(bq, maxlength);
@@ -215,7 +216,7 @@ static void drop_backlog(pa_memblockq *bq) {
int64_t boundary;
pa_assert(bq);
- boundary = bq->read_index - bq->maxrewind;
+ boundary = bq->read_index - (int64_t) bq->maxrewind;
while (bq->blocks && (bq->blocks->index + (int64_t) bq->blocks->chunk.length <= boundary))
drop_block(bq, bq->blocks);
@@ -227,10 +228,10 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) {
pa_assert(bq);
if (bq->read_index > bq->write_index) {
- size_t d = bq->read_index - bq->write_index;
+ int64_t d = bq->read_index - bq->write_index;
- if (l > d)
- l -= d;
+ if ((int64_t) l > d)
+ l -= (size_t) d;
else
return TRUE;
}
@@ -239,7 +240,7 @@ static pa_bool_t can_push(pa_memblockq *bq, size_t l) {
/* Make sure that the list doesn't get too long */
if (bq->write_index + (int64_t) l > end)
- if (bq->write_index + l - bq->read_index > bq->maxlength)
+ if (bq->write_index + (int64_t) l - bq->read_index > (int64_t) bq->maxlength)
return FALSE;
return TRUE;
@@ -294,7 +295,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
/* This entry isn't touched at all, let's skip it */
q = q->prev;
} else if (bq->write_index <= q->index &&
- bq->write_index + chunk.length >= q->index + q->chunk.length) {
+ bq->write_index + (int64_t) chunk.length >= q->index + (int64_t) q->chunk.length) {
/* This entry is fully replaced by the new entry, so let's drop it */
@@ -306,7 +307,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
/* The write index points into this memblock, so let's
* truncate or split it */
- if (bq->write_index + chunk.length < q->index + q->chunk.length) {
+ if (bq->write_index + (int64_t) chunk.length < q->index + (int64_t) q->chunk.length) {
/* We need to save the end of this memchunk */
struct list_item *p;
@@ -320,11 +321,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
pa_memblock_ref(p->chunk.memblock);
/* Calculate offset */
- d = bq->write_index + chunk.length - q->index;
+ d = (size_t) (bq->write_index + (int64_t) chunk.length - q->index);
pa_assert(d > 0);
/* Drop it from the new entry */
- p->index = q->index + d;
+ p->index = q->index + (int64_t) d;
p->chunk.length -= d;
/* Add it to the list */
@@ -339,7 +340,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
}
/* Truncate the chunk */
- if (!(q->chunk.length = bq->write_index - q->index)) {
+ if (!(q->chunk.length = (size_t) (bq->write_index - q->index))) {
struct list_item *p;
p = q;
q = q->prev;
@@ -357,8 +358,8 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
/* The job overwrites the current entry at the end, so let's drop the beginning of this entry */
- d = bq->write_index + chunk.length - q->index;
- q->index += d;
+ d = (size_t) (bq->write_index + (int64_t) chunk.length - q->index);
+ q->index += (int64_t) d;
q->chunk.index += d;
q->chunk.length -= d;
@@ -373,11 +374,11 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
/* Try to merge memory blocks */
if (q->chunk.memblock == chunk.memblock &&
- q->chunk.index + (int64_t)q->chunk.length == chunk.index &&
- bq->write_index == q->index + (int64_t)q->chunk.length) {
+ q->chunk.index + q->chunk.length == chunk.index &&
+ bq->write_index == q->index + (int64_t) q->chunk.length) {
q->chunk.length += chunk.length;
- bq->write_index += chunk.length;
+ bq->write_index += (int64_t) chunk.length;
goto finish;
}
} else
@@ -389,7 +390,7 @@ int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) {
n->chunk = chunk;
pa_memblock_ref(n->chunk.memblock);
n->index = bq->write_index;
- bq->write_index += n->chunk.length;
+ bq->write_index += (int64_t) n->chunk.length;
n->next = q ? q->next : bq->blocks;
n->prev = q;
@@ -411,10 +412,10 @@ finish:
delta = bq->write_index - old;
if (delta >= (int64_t) bq->requested) {
- delta -= bq->requested;
+ delta -= (int64_t) bq->requested;
bq->requested = 0;
} else {
- bq->requested -= delta;
+ bq->requested -= (size_t) delta;
delta = 0;
}
@@ -471,7 +472,7 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
/* How much silence shall we return? */
if (bq->current_read)
- length = bq->current_read->index - bq->read_index;
+ length = (size_t) (bq->current_read->index - bq->read_index);
else if (bq->write_index > bq->read_index)
length = (size_t) (bq->write_index - bq->read_index);
else
@@ -506,8 +507,8 @@ int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) {
pa_assert(bq->read_index >= bq->current_read->index);
d = bq->read_index - bq->current_read->index;
- chunk->index += d;
- chunk->length -= d;
+ chunk->index += (size_t) d;
+ chunk->length -= (size_t) d;
return 0;
}
@@ -533,20 +534,20 @@ void pa_memblockq_drop(pa_memblockq *bq, size_t length) {
/* We go through this piece by piece to make sure we don't
* drop more than allowed by prebuf */
- p = bq->current_read->index + bq->current_read->chunk.length;
+ p = bq->current_read->index + (int64_t) bq->current_read->chunk.length;
pa_assert(p >= bq->read_index);
d = p - bq->read_index;
if (d > (int64_t) length)
- d = length;
+ d = (int64_t) length;
bq->read_index += d;
- length -= d;
+ length -= (size_t) d;
} else {
/* The list is empty, there's nothing we could drop */
- bq->read_index += length;
+ bq->read_index += (int64_t) length;
break;
}
}
@@ -563,8 +564,8 @@ void pa_memblockq_rewind(pa_memblockq *bq, size_t length) {
/* This is kind of the inverse of pa_memblockq_drop() */
- bq->read_index -= length;
- bq->missing -= length;
+ bq->read_index -= (int64_t) length;
+ bq->missing -= (int64_t) length;
}
pa_bool_t pa_memblockq_is_readable(pa_memblockq *bq) {
@@ -628,10 +629,10 @@ void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) {
delta = bq->write_index - old;
if (delta >= (int64_t) bq->requested) {
- delta -= bq->requested;
+ delta -= (int64_t) bq->requested;
bq->requested = 0;
} else if (delta >= 0) {
- bq->requested -= delta;
+ bq->requested -= (size_t) delta;
delta = 0;
}
@@ -652,10 +653,10 @@ void pa_memblockq_flush_write(pa_memblockq *bq) {
delta = bq->write_index - old;
if (delta >= (int64_t) bq->requested) {
- delta -= bq->requested;
+ delta -= (int64_t) bq->requested;
bq->requested = 0;
} else if (delta >= 0) {
- bq->requested -= delta;
+ bq->requested -= (size_t) delta;
delta = 0;
}
@@ -874,7 +875,7 @@ int pa_memblockq_splice(pa_memblockq *bq, pa_memblockq *source) {
pa_memblock_unref(chunk.memblock);
} else
- pa_memblockq_seek(bq, chunk.length, PA_SEEK_RELATIVE);
+ pa_memblockq_seek(bq, (int64_t) chunk.length, PA_SEEK_RELATIVE);
pa_memblockq_drop(bq, chunk.length);
}
diff --git a/src/pulsecore/memblockq.h b/src/pulsecore/memblockq.h
index 4b9450f6..31f908df 100644
--- a/src/pulsecore/memblockq.h
+++ b/src/pulsecore/memblockq.h
@@ -155,7 +155,7 @@ void pa_memblockq_set_maxlength(pa_memblockq *memblockq, size_t maxlength); /* m
void pa_memblockq_set_tlength(pa_memblockq *memblockq, size_t tlength); /* might modify minreq, too */
void pa_memblockq_set_prebuf(pa_memblockq *memblockq, size_t prebuf); /* might modify minreq, too */
void pa_memblockq_set_minreq(pa_memblockq *memblockq, size_t minreq);
-void pa_memblockq_set_maxrewind(pa_memblockq *memblockq, size_t rewind); /* Set the maximum history size */
+void pa_memblockq_set_maxrewind(pa_memblockq *memblockq, size_t maxrewind); /* Set the maximum history size */
void pa_memblockq_set_silence(pa_memblockq *memblockq, pa_memchunk *silence);
/* Call pa_memchunk_willneed() for every chunk in the queue from the current read pointer to the end */
diff --git a/src/pulsecore/modargs.c b/src/pulsecore/modargs.c
index d257b4ce..9e60125e 100644
--- a/src/pulsecore/modargs.c
+++ b/src/pulsecore/modargs.c
@@ -183,7 +183,7 @@ fail:
return NULL;
}
-static void free_func(void *p, PA_GCC_UNUSED void*userdata) {
+static void free_func(void *p, void*userdata) {
struct entry *e = p;
pa_assert(e);
diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c
index dbafa8c9..9b17cb91 100644
--- a/src/pulsecore/module.c
+++ b/src/pulsecore/module.c
@@ -48,7 +48,7 @@
#define UNLOAD_POLL_TIME 2
-static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
+static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) {
pa_core *c = PA_CORE(userdata);
struct timeval ntv;
@@ -59,7 +59,7 @@ static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED
pa_module_unload_unused(c);
pa_gettimeofday(&ntv);
- pa_timeval_add(&ntv, UNLOAD_POLL_TIME*1000000);
+ pa_timeval_add(&ntv, UNLOAD_POLL_TIME*PA_USEC_PER_SEC);
m->time_restart(e, &ntv);
}
@@ -124,7 +124,7 @@ pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) {
if (m->auto_unload && !c->module_auto_unload_event) {
struct timeval ntv;
pa_gettimeofday(&ntv);
- pa_timeval_add(&ntv, UNLOAD_POLL_TIME*1000000);
+ pa_timeval_add(&ntv, UNLOAD_POLL_TIME*PA_USEC_PER_SEC);
c->module_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c);
}
@@ -190,7 +190,7 @@ void pa_module_unload_by_index(pa_core *c, uint32_t idx, pa_bool_t force) {
pa_assert(c);
pa_assert(idx != PA_IDXSET_INVALID);
- if (m->core->disallow_module_loading && !force)
+ if (c->disallow_module_loading && !force)
return;
if (!(m = pa_idxset_remove_by_index(c->modules, idx)))
diff --git a/src/pulsecore/namereg.c b/src/pulsecore/namereg.c
index 30420546..ecd8def8 100644
--- a/src/pulsecore/namereg.c
+++ b/src/pulsecore/namereg.c
@@ -45,12 +45,13 @@ struct namereg_entry {
void *data;
};
-static int is_valid_char(char c) {
+static pa_bool_t is_valid_char(char c) {
return
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '.' ||
+ c == '-' ||
c == '_';
}
@@ -77,10 +78,10 @@ char* pa_namereg_make_valid_name(const char *name) {
if (*name == 0)
return NULL;
- n = pa_xnew(char, strlen(name)+1);
+ n = pa_xmalloc(strlen(name)+1);
for (a = name, b = n; *a && (a-name < PA_NAME_MAX); a++, b++)
- *b = is_valid_char(*a) ? *a : '_';
+ *b = (char) (is_valid_char(*a) ? *a : '_');
*b = 0;
@@ -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;
@@ -136,7 +137,7 @@ const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t
return NULL;
}
- k = pa_xnew(char, l+4);
+ k = pa_xmalloc(l+4);
for (i = 2; i <= 99; i++) {
pa_snprintf(k, l+4, "%s.%u", name, i);
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/object.h b/src/pulsecore/object.h
index 7dcfa2eb..2ee4fc31 100644
--- a/src/pulsecore/object.h
+++ b/src/pulsecore/object.h
@@ -42,7 +42,7 @@ struct pa_object {
pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name));
#define pa_object_new(type) ((type*) pa_object_new_internal(sizeof(type), #type, type##_check_type)
-#define pa_object_free ((void (*) (pa_object* o)) pa_xfree)
+#define pa_object_free ((void (*) (pa_object* _obj)) pa_xfree)
int pa_object_check_type(const char *type);
diff --git a/src/pulsecore/once.c b/src/pulsecore/once.c
index 989741dc..3d4543cb 100644
--- a/src/pulsecore/once.c
+++ b/src/pulsecore/once.c
@@ -28,13 +28,13 @@
#include "once.h"
-int pa_once_begin(pa_once *control) {
+pa_bool_t pa_once_begin(pa_once *control) {
pa_mutex *m;
pa_assert(control);
if (pa_atomic_load(&control->done))
- return 0;
+ return FALSE;
pa_atomic_inc(&control->ref);
@@ -50,15 +50,17 @@ int pa_once_begin(pa_once *control) {
* wait until it is unlocked */
pa_mutex_lock(m);
+ pa_assert(pa_atomic_load(&control->done));
+
pa_once_end(control);
- return 0;
+ return FALSE;
}
pa_assert_se(m = pa_mutex_new(FALSE, FALSE));
pa_mutex_lock(m);
if (pa_atomic_ptr_cmpxchg(&control->mutex, NULL, m))
- return 1;
+ return TRUE;
pa_mutex_unlock(m);
pa_mutex_free(m);
@@ -91,4 +93,3 @@ void pa_run_once(pa_once *control, pa_once_func_t func) {
pa_once_end(control);
}
}
-
diff --git a/src/pulsecore/once.h b/src/pulsecore/once.h
index 576d40fa..c0191ef0 100644
--- a/src/pulsecore/once.h
+++ b/src/pulsecore/once.h
@@ -38,7 +38,7 @@ typedef struct pa_once {
}
/* Not to be called directly, use the macros defined below instead */
-int pa_once_begin(pa_once *o);
+pa_bool_t pa_once_begin(pa_once *o);
void pa_once_end(pa_once *o);
#define PA_ONCE_BEGIN \
diff --git a/src/pulsecore/parseaddr.c b/src/pulsecore/parseaddr.c
index f2b6b2cf..c5cd7fe7 100644
--- a/src/pulsecore/parseaddr.c
+++ b/src/pulsecore/parseaddr.c
@@ -51,20 +51,29 @@ static char *parse_host(const char *s, uint16_t *ret_port) {
if (!(e = strchr(s+1, ']')))
return NULL;
- if (e[1] == ':')
- *ret_port = atoi(e+2);
- else if (e[1] != 0)
+ if (e[1] == ':') {
+ uint32_t p;
+
+ if (pa_atou(e+2, &p) < 0)
+ return NULL;
+
+ *ret_port = (uint16_t) p;
+ } else if (e[1] != 0)
return NULL;
- return pa_xstrndup(s+1, e-s-1);
+ return pa_xstrndup(s+1, (size_t) (e-s-1));
} else {
char *e;
+ uint32_t p;
if (!(e = strrchr(s, ':')))
return pa_xstrdup(s);
- *ret_port = atoi(e+1);
- return pa_xstrndup(s, e-s);
+ if (pa_atou(e+1, &p) < 0)
+ return NULL;
+
+ *ret_port = (uint16_t) p;
+ return pa_xstrndup(s, (size_t) (e-s));
}
}
diff --git a/src/pulsecore/pdispatch.c b/src/pulsecore/pdispatch.c
index e6a6ae4d..00df0f79 100644
--- a/src/pulsecore/pdispatch.c
+++ b/src/pulsecore/pdispatch.c
@@ -255,7 +255,7 @@ finish:
return ret;
}
-static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) {
+static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, const struct timeval *tv, void *userdata) {
struct reply_info*r = userdata;
pa_assert(r);
diff --git a/src/pulsecore/pid.c b/src/pulsecore/pid.c
index addb17cc..bf9ba983 100644
--- a/src/pulsecore/pid.c
+++ b/src/pulsecore/pid.c
@@ -73,6 +73,7 @@ static pid_t read_pid(const char *fn, int fd) {
if (pa_atou(t, &pid) < 0) {
pa_log_warn("Failed to parse PID file '%s'", fn);
+ errno = EINVAL;
return (pid_t) -1;
}
@@ -110,7 +111,7 @@ static int open_pid_file(const char *fn, int mode) {
goto fail;
}
- /* Does the file still exist in the file system? When ye, w're done, otherwise restart */
+ /* Does the file still exist in the file system? When yes, we're done, otherwise restart */
if (st.st_nlink >= 1)
break;
@@ -131,8 +132,10 @@ static int open_pid_file(const char *fn, int mode) {
fail:
if (fd >= 0) {
+ int saved_errno = errno;
pa_lock_fd(fd, 0);
pa_close(fd);
+ errno = saved_errno;
}
return -1;
@@ -154,8 +157,11 @@ static int proc_name_ours(pid_t pid, const char *procname) {
char stored[64];
if (!(fgets(stored, sizeof(stored), f))) {
+ int saved_errno = feof(f) ? EINVAL : errno;
pa_log_info("Failed to read from %s: %s", bn, feof(f) ? "EOF" : pa_cstrerror(errno));
fclose(f);
+
+ errno = saved_errno;
return -1;
}
@@ -165,20 +171,22 @@ static int proc_name_ours(pid_t pid, const char *procname) {
good = pa_startswith(stored, expected);
pa_xfree(expected);
-#if !defined(__OPTIMIZE__)
+/*#if !defined(__OPTIMIZE__)*/
if (!good) {
/* libtool likes to rename our binary names ... */
expected = pa_sprintf_malloc("%lu (lt-%s)", (unsigned long) pid, procname);
good = pa_startswith(stored, expected);
pa_xfree(expected);
}
-#endif
+/*#endif*/
return !!good;
}
-#endif
+#else
return 1;
+#endif
+
}
/* Create a new PID file for the current process. */
@@ -203,6 +211,7 @@ int pa_pid_file_create(const char *procname) {
if ((pid = read_pid(fn, fd)) == (pid_t) -1)
pa_log_warn("Corrupt PID file, overwriting.");
else if (pid > 0) {
+ int ours = 1;
#ifdef OS_IS_WIN32
if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)) != NULL) {
@@ -210,11 +219,13 @@ int pa_pid_file_create(const char *procname) {
#else
if (kill(pid, 0) >= 0 || errno != ESRCH) {
#endif
- int ours = 1;
if (procname)
- if ((ours = proc_name_ours(pid, procname)) < 0)
+ if ((ours = proc_name_ours(pid, procname)) < 0) {
+ pa_log_warn("Could not check to see if pid %lu is a pulseaudio process. "
+ "Asssuming it is and the daemon is already running.", (unsigned long) pid);
goto fail;
+ }
if (ours) {
pa_log("Daemon already running.");
@@ -227,7 +238,7 @@ int pa_pid_file_create(const char *procname) {
}
/* Overwrite the current PID file */
- if (lseek(fd, 0, SEEK_SET) == (off_t) -1 || ftruncate(fd, 0) < 0) {
+ if (lseek(fd, (off_t) 0, SEEK_SET) == (off_t) -1 || ftruncate(fd, (off_t) 0) < 0) {
pa_log("Failed to truncate PID file '%s': %s", fn, pa_cstrerror(errno));
goto fail;
}
@@ -280,7 +291,7 @@ int pa_pid_file_remove(void) {
goto fail;
}
- if (ftruncate(fd, 0) < 0) {
+ if (ftruncate(fd, (off_t) 0) < 0) {
pa_log_warn("Failed to truncate PID file '%s': %s", fn, pa_cstrerror(errno));
goto fail;
}
@@ -342,8 +353,13 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {
if (!(fn = pa_runtime_path("pid")))
goto fail;
- if ((fd = open_pid_file(fn, O_RDONLY)) < 0)
+ if ((fd = open_pid_file(fn, O_RDONLY)) < 0) {
+
+ if (errno == ENOENT)
+ errno = ESRCH;
+
goto fail;
+ }
if ((*pid = read_pid(fn, fd)) == (pid_t) -1)
goto fail;
@@ -354,8 +370,10 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {
if ((ours = proc_name_ours(*pid, procname)) < 0)
goto fail;
- if (!ours)
+ if (!ours) {
+ errno = ESRCH;
goto fail;
+ }
}
ret = kill(*pid, sig);
@@ -363,8 +381,10 @@ int pa_pid_file_kill(int sig, pid_t *pid, const char *procname) {
fail:
if (fd >= 0) {
+ int saved_errno = errno;
pa_lock_fd(fd, 0);
pa_close(fd);
+ errno = saved_errno;
}
#ifdef __linux__
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-esound.c b/src/pulsecore/protocol-esound.c
index 4f121a3a..460119a9 100644
--- a/src/pulsecore/protocol-esound.c
+++ b/src/pulsecore/protocol-esound.c
@@ -184,7 +184,7 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = {
{ sizeof(int), esd_proto_sample_free_or_play, "sample play" }, /* 8 */
{ sizeof(int), NULL, "sample loop" },
{ sizeof(int), NULL, "sample stop" },
- { -1, NULL, "TODO: sample kill" },
+ { (size_t) -1, NULL, "TODO: sample kill" },
{ ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "standby" }, /* NOOP! */
{ ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "resume" }, /* NOOP! */ /* 13 */
@@ -194,8 +194,8 @@ static struct proto_handler proto_map[ESD_PROTO_MAX] = {
{ sizeof(int), esd_proto_server_info, "server info" },
{ sizeof(int), esd_proto_all_info, "all info" },
- { -1, NULL, "TODO: subscribe" },
- { -1, NULL, "TODO: unsubscribe" },
+ { (size_t) -1, NULL, "TODO: subscribe" },
+ { (size_t) -1, NULL, "TODO: unsubscribe" },
{ 3 * sizeof(int), esd_proto_stream_pan, "stream pan"},
{ 3 * sizeof(int), NULL, "sample pan" },
@@ -309,7 +309,7 @@ static void connection_write(connection *c, const void *data, size_t length) {
static void format_esd2native(int format, pa_bool_t swap_bytes, pa_sample_spec *ss) {
pa_assert(ss);
- ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1;
+ ss->channels = (uint8_t) (((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1);
if ((format & ESD_MASK_BITS) == ESD_BITS16)
ss->format = swap_bytes ? PA_SAMPLE_S16RE : PA_SAMPLE_S16NE;
else
@@ -334,7 +334,7 @@ static int format_native2esd(pa_sample_spec *ss) {
/*** esound commands ***/
-static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_connect(connection *c, esd_proto_t request, const void *data, size_t length) {
uint32_t ekey;
int ok;
@@ -377,7 +377,7 @@ static int esd_proto_connect(connection *c, PA_GCC_UNUSED esd_proto_t request, c
return 0;
}
-static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_stream_play(connection *c, esd_proto_t request, const void *data, size_t length) {
char name[ESD_NAME_MAX], *utf8_name;
int32_t format, rate;
pa_sample_spec ss;
@@ -397,7 +397,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques
rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
data = (const char*) data + sizeof(int32_t);
- ss.rate = rate;
+ ss.rate = (uint32_t) rate;
format_esd2native(format, c->swap_byte_order, &ss);
CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification");
@@ -430,7 +430,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques
CHECK_VALIDITY(c->sink_input, "Failed to create sink input.");
- l = (size_t) (pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
+ l = (size_t) ((double) pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS);
c->input_memblockq = pa_memblockq_new(
0,
l,
@@ -455,7 +455,7 @@ static int esd_proto_stream_play(connection *c, PA_GCC_UNUSED esd_proto_t reques
c->protocol->n_player++;
- pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq));
+ pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));
pa_sink_input_put(c->sink_input);
@@ -482,7 +482,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi
rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
data = (const char*) data + sizeof(int32_t);
- ss.rate = rate;
+ ss.rate = (uint32_t) rate;
format_esd2native(format, c->swap_byte_order, &ss);
CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification.");
@@ -561,7 +561,7 @@ static int esd_proto_stream_record(connection *c, esd_proto_t request, const voi
return 0;
}
-static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_get_latency(connection *c, esd_proto_t request, const void *data, size_t length) {
pa_sink *sink;
int32_t latency;
@@ -572,7 +572,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques
if (!(sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1)))
latency = 0;
else {
- double usec = pa_sink_get_latency(sink);
+ double usec = (double) pa_sink_get_latency(sink);
latency = (int) ((usec*44100)/1000000);
}
@@ -581,7 +581,7 @@ static int esd_proto_get_latency(connection *c, PA_GCC_UNUSED esd_proto_t reques
return 0;
}
-static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_server_info(connection *c, esd_proto_t request, const void *data, size_t length) {
int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16;
int32_t response;
pa_sink *sink;
@@ -591,7 +591,7 @@ static int esd_proto_server_info(connection *c, PA_GCC_UNUSED esd_proto_t reques
pa_assert(length == sizeof(int32_t));
if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1))) {
- rate = sink->sample_spec.rate;
+ rate = (int32_t) sink->sample_spec.rate;
format = format_native2esd(&sink->sample_spec);
}
@@ -641,9 +641,9 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
if (conn->sink_input) {
pa_cvolume volume = *pa_sink_input_get_volume(conn->sink_input);
- rate = conn->sink_input->sample_spec.rate;
- lvolume = (volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM;
- rvolume = (volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM;
+ rate = (int32_t) conn->sink_input->sample_spec.rate;
+ lvolume = (int32_t) ((volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
+ rvolume = (int32_t) ((volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
format = format_native2esd(&conn->sink_input->sample_spec);
}
@@ -706,15 +706,15 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
connection_write(c, name, ESD_NAME_MAX);
/* rate */
- rate = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, ce->sample_spec.rate);
+ rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ce->sample_spec.rate);
connection_write(c, &rate, sizeof(int32_t));
/* left */
- lvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
+ lvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));
connection_write(c, &lvolume, sizeof(int32_t));
/*right*/
- rvolume = PA_MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM);
+ rvolume = PA_MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) ((ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM));
connection_write(c, &rvolume, sizeof(int32_t));
/*format*/
@@ -736,7 +736,7 @@ static int esd_proto_all_info(connection *c, esd_proto_t request, const void *da
return 0;
}
-static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_stream_pan(connection *c, esd_proto_t request, const void *data, size_t length) {
int32_t ok;
uint32_t idx, lvolume, rvolume;
connection *conn;
@@ -772,7 +772,7 @@ static int esd_proto_stream_pan(connection *c, PA_GCC_UNUSED esd_proto_t request
return 0;
}
-static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_sample_cache(connection *c, esd_proto_t request, const void *data, size_t length) {
pa_sample_spec ss;
int32_t format, rate, sc_length;
uint32_t idx;
@@ -790,7 +790,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque
rate = PA_MAYBE_INT32_SWAP(c->swap_byte_order, rate);
data = (const char*)data + sizeof(int32_t);
- ss.rate = rate;
+ ss.rate = (uint32_t) rate;
format_esd2native(format, c->swap_byte_order, &ss);
CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification.");
@@ -807,9 +807,9 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque
CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name.");
pa_assert(!c->scache.memchunk.memblock);
- c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, sc_length);
+ c->scache.memchunk.memblock = pa_memblock_new(c->protocol->core->mempool, (size_t) sc_length);
c->scache.memchunk.index = 0;
- c->scache.memchunk.length = sc_length;
+ c->scache.memchunk.length = (size_t) sc_length;
c->scache.sample_spec = ss;
pa_assert(!c->scache.name);
c->scache.name = pa_xstrdup(name);
@@ -824,7 +824,7 @@ static int esd_proto_sample_cache(connection *c, PA_GCC_UNUSED esd_proto_t reque
return 0;
}
-static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) {
+static int esd_proto_sample_get_id(connection *c, esd_proto_t request, const void *data, size_t length) {
int32_t ok;
uint32_t idx;
char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1];
@@ -840,7 +840,7 @@ static int esd_proto_sample_get_id(connection *c, PA_GCC_UNUSED esd_proto_t requ
ok = -1;
if ((idx = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID)
- ok = idx + 1;
+ ok = (int32_t) idx + 1;
connection_write(c, &ok, sizeof(int32_t));
@@ -867,12 +867,12 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con
if ((sink = pa_namereg_get(c->protocol->core, c->options->default_sink, PA_NAMEREG_SINK, 1)))
if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM, c->client->proplist, NULL) >= 0)
- ok = idx + 1;
+ ok = (int32_t) idx + 1;
} else {
pa_assert(request == ESD_PROTO_SAMPLE_FREE);
if (pa_scache_remove_item(c->protocol->core, name) >= 0)
- ok = idx + 1;
+ ok = (int32_t) idx + 1;
}
}
@@ -881,7 +881,7 @@ static int esd_proto_sample_free_or_play(connection *c, esd_proto_t request, con
return 0;
}
-static int esd_proto_standby_or_resume(connection *c, PA_GCC_UNUSED esd_proto_t request, PA_GCC_UNUSED const void *data, PA_GCC_UNUSED size_t length) {
+static int esd_proto_standby_or_resume(connection *c, esd_proto_t request, const void *data, size_t length) {
int32_t ok;
connection_assert_ref(c);
@@ -919,7 +919,9 @@ static int do_read(connection *c) {
return -1;
}
- if ((c->read_data_length+= r) >= sizeof(c->request)) {
+ c->read_data_length += (size_t) r;
+
+ if (c->read_data_length >= sizeof(c->request)) {
struct proto_handler *handler;
c->request = PA_MAYBE_INT32_SWAP(c->swap_byte_order, c->request);
@@ -970,7 +972,8 @@ static int do_read(connection *c) {
return -1;
}
- if ((c->read_data_length += r) >= handler->data_length) {
+ c->read_data_length += (size_t) r;
+ if (c->read_data_length >= handler->data_length) {
size_t l = c->read_data_length;
pa_assert(handler->proc);
@@ -1000,7 +1003,7 @@ static int do_read(connection *c) {
return -1;
}
- c->scache.memchunk.index += r;
+ c->scache.memchunk.index += (size_t) r;
pa_assert(c->scache.memchunk.index <= c->scache.memchunk.length);
if (c->scache.memchunk.index == c->scache.memchunk.length) {
@@ -1033,7 +1036,7 @@ static int do_read(connection *c) {
/* pa_log("STREAMING_DATA"); */
- if (!(l = pa_atomic_load(&c->playback.missing)))
+ if (!(l = (size_t) pa_atomic_load(&c->playback.missing)))
return 0;
if (c->playback.current_memblock) {
@@ -1071,12 +1074,12 @@ static int do_read(connection *c) {
chunk.memblock = c->playback.current_memblock;
chunk.index = c->playback.memblock_index;
- chunk.length = r;
+ chunk.length = (size_t) r;
- c->playback.memblock_index += r;
+ c->playback.memblock_index += (size_t) r;
pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
- pa_atomic_sub(&c->playback.missing, r);
+ pa_atomic_sub(&c->playback.missing, (int) r);
}
return 0;
@@ -1100,7 +1103,8 @@ static int do_write(connection *c) {
return -1;
}
- if ((c->write_data_index +=r) >= c->write_data_length)
+ c->write_data_index += (size_t) r;
+ if (c->write_data_index >= c->write_data_length)
c->write_data_length = c->write_data_index = 0;
} else if (c->state == ESD_STREAMING_DATA && c->source_output) {
@@ -1129,7 +1133,7 @@ static int do_write(connection *c) {
return -1;
}
- pa_memblockq_drop(c->output_memblockq, r);
+ pa_memblockq_drop(c->output_memblockq, (size_t) r);
}
return 0;
@@ -1288,7 +1292,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
m = pa_memblockq_pop_missing(c->input_memblockq);
if (m > 0)
- if (pa_atomic_add(&c->playback.missing, m) <= 0)
+ if (pa_atomic_add(&c->playback.missing, (int) m) <= 0)
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);
return 0;
@@ -1574,7 +1578,7 @@ int pa_esound_options_parse(pa_esound_options *o, pa_core *c, pa_modargs *ma) {
if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {
pa_ip_acl *ipa;
- if (!(o->auth_ip_acl = pa_ip_acl_new(acl))) {
+ if (!(ipa = pa_ip_acl_new(acl))) {
pa_log("Failed to parse IP ACL '%s'", acl);
return -1;
}
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index b9f6f083..56e86cb4 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -469,51 +469,102 @@ static int record_stream_process_msg(pa_msgobject *o, int code, void*userdata, i
return 0;
}
-static void fix_record_buffer_attr_pre(record_stream *s, pa_bool_t adjust_latency, uint32_t *maxlength, uint32_t *fragsize) {
+static void fix_record_buffer_attr_pre(
+ record_stream *s,
+ pa_bool_t adjust_latency,
+ pa_bool_t early_requests,
+ uint32_t *maxlength,
+ uint32_t *fragsize) {
+
+ size_t frame_size;
+ pa_usec_t orig_fragsize_usec, fragsize_usec, source_usec;
+
pa_assert(s);
pa_assert(maxlength);
pa_assert(fragsize);
+ frame_size = pa_frame_size(&s->source_output->sample_spec);
+
if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
*maxlength = MAX_MEMBLOCKQ_LENGTH;
if (*maxlength <= 0)
- *maxlength = pa_frame_size(&s->source_output->sample_spec);
+ *maxlength = (uint32_t) frame_size;
if (*fragsize == (uint32_t) -1)
- *fragsize = pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec);
+ *fragsize = (uint32_t) pa_usec_to_bytes(DEFAULT_FRAGSIZE_MSEC*PA_USEC_PER_MSEC, &s->source_output->sample_spec);
if (*fragsize <= 0)
- *fragsize = pa_frame_size(&s->source_output->sample_spec);
+ *fragsize = (uint32_t) frame_size;
+
+ orig_fragsize_usec = fragsize_usec = pa_bytes_to_usec(*fragsize, &s->source_output->sample_spec);
- if (adjust_latency) {
- pa_usec_t fragsize_usec;
+ if (early_requests) {
+
+ /* In early request mode we need to emulate the classic
+ * fragment-based playback model. We do this setting the source
+ * latency to the fragment size. */
+
+ source_usec = fragsize_usec;
+
+ } else if (adjust_latency) {
/* So, the user asked us to adjust the latency according to
* what the source can provide. Half the latency will be
* spent on the hw buffer, half of it in the async buffer
* queue we maintain for each client. */
- fragsize_usec = pa_bytes_to_usec(*fragsize, &s->source_output->sample_spec);
+ source_usec = fragsize_usec/2;
+
+ } else {
+
+ /* Ok, the user didn't ask us to adjust the latency, hence we
+ * don't */
- s->source_latency = pa_source_output_set_requested_latency(s->source_output, fragsize_usec/2);
+ source_usec = 0;
+ }
+
+ if (source_usec > 0)
+ s->source_latency = pa_source_output_set_requested_latency(s->source_output, source_usec);
+ else
+ s->source_latency = 0;
+
+ if (early_requests) {
+
+ /* Ok, we didn't necessarily get what we were asking for, so
+ * let's tell the user */
+
+ fragsize_usec = s->source_latency;
+
+ } else if (adjust_latency) {
+
+ /* Now subtract what we actually got */
if (fragsize_usec >= s->source_latency*2)
fragsize_usec -= s->source_latency;
else
fragsize_usec = s->source_latency;
+ }
- *fragsize = pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec);
- } else
- s->source_latency = 0;
+ if (pa_usec_to_bytes(orig_fragsize_usec, &s->source_output->sample_spec) !=
+ pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec))
+
+ *fragsize = (uint32_t) pa_usec_to_bytes(fragsize_usec, &s->source_output->sample_spec);
+
+ if (*fragsize <= 0)
+ *fragsize = (uint32_t) frame_size;
}
-static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, uint32_t *fragsize) {
+static void fix_record_buffer_attr_post(
+ record_stream *s,
+ uint32_t *maxlength,
+ uint32_t *fragsize) {
+
size_t base;
pa_assert(s);
pa_assert(maxlength);
pa_assert(fragsize);
- *maxlength = pa_memblockq_get_maxlength(s->memblockq);
+ *maxlength = (uint32_t) pa_memblockq_get_maxlength(s->memblockq);
base = pa_frame_size(&s->source_output->sample_spec);
@@ -524,7 +575,7 @@ static void fix_record_buffer_attr_post(record_stream *s, uint32_t *maxlength, u
if (s->fragment_size > *maxlength)
s->fragment_size = *maxlength;
- *fragsize = s->fragment_size;
+ *fragsize = (uint32_t) s->fragment_size;
}
static record_stream* record_stream_new(
@@ -538,7 +589,8 @@ static record_stream* record_stream_new(
pa_source_output_flags_t flags,
pa_proplist *p,
pa_bool_t adjust_latency,
- pa_sink_input *direct_on_input) {
+ pa_sink_input *direct_on_input,
+ pa_bool_t early_requests) {
record_stream *s;
pa_source_output *source_output;
@@ -584,7 +636,7 @@ static record_stream* record_stream_new(
s->source_output->suspend = source_output_suspend_cb;
s->source_output->userdata = s;
- fix_record_buffer_attr_pre(s, adjust_latency, maxlength, fragsize);
+ fix_record_buffer_attr_pre(s, adjust_latency, early_requests, maxlength, fragsize);
s->memblockq = pa_memblockq_new(
0,
@@ -666,10 +718,10 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
uint32_t l = 0;
for (;;) {
- if ((l = pa_atomic_load(&s->missing)) <= 0)
+ if ((l = (uint32_t) pa_atomic_load(&s->missing)) <= 0)
break;
- if (pa_atomic_cmpxchg(&s->missing, l, 0))
+ if (pa_atomic_cmpxchg(&s->missing, (int) l, 0))
break;
}
@@ -690,6 +742,8 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
case PLAYBACK_STREAM_MESSAGE_UNDERFLOW: {
pa_tagstruct *t;
+/* pa_log("signalling underflow"); */
+
/* Report that we're empty */
t = pa_tagstruct_new(NULL, 0);
pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW);
@@ -734,9 +788,17 @@ static int playback_stream_process_msg(pa_msgobject *o, int code, void*userdata,
return 0;
}
-static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_latency, uint32_t *maxlength, uint32_t *tlength, uint32_t* prebuf, uint32_t* minreq) {
+static void fix_playback_buffer_attr_pre(
+ playback_stream *s,
+ pa_bool_t adjust_latency,
+ pa_bool_t early_requests,
+ uint32_t *maxlength,
+ uint32_t *tlength,
+ uint32_t* prebuf,
+ uint32_t* minreq) {
+
size_t frame_size;
- pa_usec_t tlength_usec, minreq_usec, sink_usec;
+ pa_usec_t orig_tlength_usec, tlength_usec, orig_minreq_usec, minreq_usec, sink_usec;
pa_assert(s);
pa_assert(maxlength);
@@ -749,29 +811,39 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la
if (*maxlength == (uint32_t) -1 || *maxlength > MAX_MEMBLOCKQ_LENGTH)
*maxlength = MAX_MEMBLOCKQ_LENGTH;
if (*maxlength <= 0)
- *maxlength = frame_size;
+ *maxlength = (uint32_t) frame_size;
if (*tlength == (uint32_t) -1)
- *tlength = pa_usec_to_bytes(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
+ *tlength = (uint32_t) pa_usec_to_bytes_round_up(DEFAULT_TLENGTH_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
if (*tlength <= 0)
- *tlength = frame_size;
+ *tlength = (uint32_t) frame_size;
if (*minreq == (uint32_t) -1)
- *minreq = pa_usec_to_bytes(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
+ *minreq = (uint32_t) pa_usec_to_bytes_round_up(DEFAULT_PROCESS_MSEC*PA_USEC_PER_MSEC, &s->sink_input->sample_spec);
if (*minreq <= 0)
- *minreq = frame_size;
+ *minreq = (uint32_t) frame_size;
if (*tlength < *minreq+frame_size)
- *tlength = *minreq+frame_size;
+ *tlength = *minreq+(uint32_t) frame_size;
- tlength_usec = pa_bytes_to_usec(*tlength, &s->sink_input->sample_spec);
- minreq_usec = pa_bytes_to_usec(*minreq, &s->sink_input->sample_spec);
+ orig_tlength_usec = tlength_usec = pa_bytes_to_usec(*tlength, &s->sink_input->sample_spec);
+ orig_minreq_usec = minreq_usec = pa_bytes_to_usec(*minreq, &s->sink_input->sample_spec);
pa_log_info("Requested tlength=%0.2f ms, minreq=%0.2f ms",
(double) tlength_usec / PA_USEC_PER_MSEC,
(double) minreq_usec / PA_USEC_PER_MSEC);
- if (adjust_latency) {
+ if (early_requests) {
+
+ /* In early request mode we need to emulate the classic
+ * fragment-based playback model. We do this setting the sink
+ * latency to the fragment size. */
+
+ sink_usec = minreq_usec;
+
+ pa_log_debug("Early requests mode enabled, configuring sink latency to minreq.");
+
+ } else if (adjust_latency) {
/* So, the user asked us to adjust the latency of the stream
* buffer according to the what the sink can provide. The
@@ -795,6 +867,8 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la
else
sink_usec = 0;
+ pa_log_debug("Adjust latency mode enabled, configuring sink latency to half of overall latency.");
+
} else {
/* Ok, the user didn't ask us to adjust the latency, but we
@@ -805,11 +879,21 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la
sink_usec = (tlength_usec - minreq_usec*2);
else
sink_usec = 0;
+
+ pa_log_debug("Traditional mode enabled, modifying sink usec only for compat with minreq.");
}
s->sink_latency = pa_sink_input_set_requested_latency(s->sink_input, sink_usec);
- if (adjust_latency) {
+ if (early_requests) {
+
+ /* Ok, we didn't necessarily get what we were asking for, so
+ * let's tell the user */
+
+ minreq_usec = s->sink_latency;
+
+ } else if (adjust_latency) {
+
/* Ok, we didn't necessarily get what we were asking for, so
* let's subtract from what we asked for for the remaining
* buffer space */
@@ -823,22 +907,33 @@ static void fix_playback_buffer_attr_pre(playback_stream *s, pa_bool_t adjust_la
if (tlength_usec < s->sink_latency + 2*minreq_usec)
tlength_usec = s->sink_latency + 2*minreq_usec;
- *tlength = pa_usec_to_bytes(tlength_usec, &s->sink_input->sample_spec);
- *minreq = pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec);
+ if (pa_usec_to_bytes_round_up(orig_tlength_usec, &s->sink_input->sample_spec) !=
+ pa_usec_to_bytes_round_up(tlength_usec, &s->sink_input->sample_spec))
+ *tlength = (uint32_t) pa_usec_to_bytes_round_up(tlength_usec, &s->sink_input->sample_spec);
+
+ if (pa_usec_to_bytes(orig_minreq_usec, &s->sink_input->sample_spec) !=
+ pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec))
+ *minreq = (uint32_t) pa_usec_to_bytes(minreq_usec, &s->sink_input->sample_spec);
if (*minreq <= 0) {
- *minreq += frame_size;
- *tlength += frame_size*2;
+ *minreq = (uint32_t) frame_size;
+ *tlength += (uint32_t) frame_size*2;
}
if (*tlength <= *minreq)
- *tlength = *minreq*2 + frame_size;
+ *tlength = *minreq*2 + (uint32_t) frame_size;
if (*prebuf == (uint32_t) -1 || *prebuf > *tlength)
*prebuf = *tlength;
}
-static void fix_playback_buffer_attr_post(playback_stream *s, uint32_t *maxlength, uint32_t *tlength, uint32_t* prebuf, uint32_t* minreq) {
+static void fix_playback_buffer_attr_post(
+ playback_stream *s,
+ uint32_t *maxlength,
+ uint32_t *tlength,
+ uint32_t* prebuf,
+ uint32_t* minreq) {
+
pa_assert(s);
pa_assert(maxlength);
pa_assert(tlength);
@@ -864,11 +959,13 @@ static playback_stream* playback_stream_new(
uint32_t *minreq,
pa_cvolume *volume,
pa_bool_t muted,
+ pa_bool_t muted_set,
uint32_t syncid,
uint32_t *missing,
pa_sink_input_flags_t flags,
pa_proplist *p,
- pa_bool_t adjust_latency) {
+ pa_bool_t adjust_latency,
+ pa_bool_t early_requests) {
playback_stream *s, *ssync;
pa_sink_input *sink_input;
@@ -883,7 +980,6 @@ static playback_stream* playback_stream_new(
pa_assert(tlength);
pa_assert(prebuf);
pa_assert(minreq);
- pa_assert(volume);
pa_assert(missing);
pa_assert(p);
@@ -916,8 +1012,10 @@ static playback_stream* playback_stream_new(
data.sink = sink;
pa_sink_input_new_data_set_sample_spec(&data, ss);
pa_sink_input_new_data_set_channel_map(&data, map);
- pa_sink_input_new_data_set_volume(&data, volume);
- pa_sink_input_new_data_set_muted(&data, muted);
+ if (volume)
+ pa_sink_input_new_data_set_volume(&data, volume);
+ if (muted_set)
+ pa_sink_input_new_data_set_muted(&data, muted);
data.sync_base = ssync ? ssync->sink_input : NULL;
sink_input = pa_sink_input_new(c->protocol->core, &data, flags);
@@ -949,7 +1047,7 @@ static playback_stream* playback_stream_new(
start_index = ssync ? pa_memblockq_get_read_index(ssync->memblockq) : 0;
- fix_playback_buffer_attr_pre(s, adjust_latency, maxlength, tlength, prebuf, minreq);
+ fix_playback_buffer_attr_pre(s, adjust_latency, early_requests, maxlength, tlength, prebuf, minreq);
pa_sink_input_get_silence(sink_input, &silence);
s->memblockq = pa_memblockq_new(
@@ -982,7 +1080,6 @@ static playback_stream* playback_stream_new(
return s;
}
-
/* Called from thread context */
static void playback_stream_request_bytes(playback_stream *s) {
size_t m, previous_missing;
@@ -996,7 +1093,7 @@ static void playback_stream_request_bytes(playback_stream *s) {
/* pa_log("request_bytes(%lu)", (unsigned long) m); */
- previous_missing = pa_atomic_add(&s->missing, m);
+ previous_missing = (size_t) pa_atomic_add(&s->missing, (int) m);
if (pa_memblockq_prebuf_active(s->memblockq) ||
(previous_missing < s->minreq && previous_missing+m >= s->minreq))
@@ -1142,7 +1239,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
pa_log_debug("Requesting rewind due to end of underrun.");
pa_sink_input_request_rewind(s->sink_input,
- s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for,
+ (size_t) (s->sink_input->thread_info.underrun_for == (size_t) -1 ? 0 : s->sink_input->thread_info.underrun_for),
FALSE, TRUE);
}
@@ -1156,7 +1253,7 @@ static void handle_seek(playback_stream *s, int64_t indexw) {
* let's have it usk us again */
pa_log_debug("Requesting rewind due to rewrite.");
- pa_sink_input_request_rewind(s->sink_input, indexr - indexw, TRUE, FALSE);
+ pa_sink_input_request_rewind(s->sink_input, (size_t) (indexr - indexw), TRUE, FALSE);
}
}
@@ -1196,7 +1293,7 @@ static int sink_input_process_msg(pa_msgobject *o, int code, void *userdata, int
if (pa_memblockq_push_align(s->memblockq, chunk) < 0) {
pa_log_warn("Failed to push data into queue");
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(s), PLAYBACK_STREAM_MESSAGE_OVERFLOW, NULL, 0, NULL, NULL);
- pa_memblockq_seek(s->memblockq, chunk->length, PA_SEEK_RELATIVE);
+ pa_memblockq_seek(s->memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE);
}
handle_seek(s, windex);
@@ -1426,7 +1523,7 @@ static void sink_input_moved_cb(pa_sink_input *i) {
prebuf = (uint32_t) pa_memblockq_get_prebuf(s->memblockq);
minreq = (uint32_t) pa_memblockq_get_minreq(s->memblockq);
- fix_playback_buffer_attr_pre(s, TRUE, &maxlength, &tlength, &prebuf, &minreq);
+ fix_playback_buffer_attr_pre(s, TRUE, FALSE, &maxlength, &tlength, &prebuf, &minreq);
pa_memblockq_set_maxlength(s->memblockq, maxlength);
pa_memblockq_set_tlength(s->memblockq, tlength);
pa_memblockq_set_prebuf(s->memblockq, prebuf);
@@ -1525,7 +1622,7 @@ static void source_output_moved_cb(pa_source_output *o) {
fragsize = (uint32_t) s->fragment_size;
maxlength = (uint32_t) pa_memblockq_get_length(s->memblockq);
- fix_record_buffer_attr_pre(s, TRUE, &maxlength, &fragsize);
+ fix_record_buffer_attr_pre(s, TRUE, FALSE, &maxlength, &fragsize);
pa_memblockq_set_maxlength(s->memblockq, maxlength);
fix_record_buffer_attr_post(s, &maxlength, &fragsize);
@@ -1572,7 +1669,7 @@ static pa_tagstruct *reply_new(uint32_t tag) {
return reply;
}
-static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
playback_stream *s;
uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid, missing;
@@ -1592,10 +1689,14 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
no_move = FALSE,
variable_rate = FALSE,
muted = FALSE,
- adjust_latency = FALSE;
+ adjust_latency = FALSE,
+ early_requests = FALSE,
+ dont_inhibit_auto_suspend = FALSE,
+ muted_set = FALSE;
pa_sink_input_flags_t flags = 0;
pa_proplist *p;
+ pa_bool_t volume_set = TRUE;
pa_native_connection_assert_ref(c);
pa_assert(t);
@@ -1621,7 +1722,9 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(sink_name)), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID);
@@ -1660,6 +1763,26 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
}
}
+ if (c->version >= 14) {
+
+ if (pa_tagstruct_get_boolean(t, &volume_set) < 0 ||
+ pa_tagstruct_get_boolean(t, &early_requests) < 0) {
+ protocol_error(c);
+ pa_proplist_free(p);
+ return;
+ }
+ }
+
+ if (c->version >= 15) {
+
+ if (pa_tagstruct_get_boolean(t, &muted_set) < 0 ||
+ pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0) {
+ protocol_error(c);
+ pa_proplist_free(p);
+ return;
+ }
+ }
+
if (!pa_tagstruct_eof(t)) {
protocol_error(c);
pa_proplist_free(p);
@@ -1691,9 +1814,14 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
(fix_rate ? PA_SINK_INPUT_FIX_RATE : 0) |
(fix_channels ? PA_SINK_INPUT_FIX_CHANNELS : 0) |
(no_move ? PA_SINK_INPUT_DONT_MOVE : 0) |
- (variable_rate ? PA_SINK_INPUT_VARIABLE_RATE : 0);
+ (variable_rate ? PA_SINK_INPUT_VARIABLE_RATE : 0) |
+ (dont_inhibit_auto_suspend ? PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND : 0);
+
+ /* Only since protocol version 15 there's a seperate muted_set
+ * flag. For older versions we synthesize it here */
+ muted_set = muted_set || muted;
- s = playback_stream_new(c, sink, &ss, &map, &maxlength, &tlength, &prebuf, &minreq, &volume, muted, syncid, &missing, flags, p, adjust_latency);
+ s = playback_stream_new(c, sink, &ss, &map, &maxlength, &tlength, &prebuf, &minreq, volume_set ? &volume : NULL, muted, muted_set, syncid, &missing, flags, p, adjust_latency, early_requests);
pa_proplist_free(p);
CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID);
@@ -1735,7 +1863,7 @@ static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t channel;
@@ -1793,7 +1921,7 @@ static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
record_stream *s;
uint32_t maxlength, fragment_size;
@@ -1813,7 +1941,9 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
no_move = FALSE,
variable_rate = FALSE,
adjust_latency = FALSE,
- peak_detect = FALSE;
+ peak_detect = FALSE,
+ early_requests = FALSE,
+ dont_inhibit_auto_suspend = FALSE;
pa_source_output_flags_t flags = 0;
pa_proplist *p;
uint32_t direct_on_input_idx = PA_INVALID_INDEX;
@@ -1835,9 +1965,11 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
+ CHECK_VALIDITY(c->pstream, !source_name || pa_namereg_is_valid_name(source_name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, source_index == PA_INVALID_INDEX || !source_name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !source_name || source_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID);
- CHECK_VALIDITY(c->pstream, source_index != PA_INVALID_INDEX || !source_name || (*source_name && pa_utf8_valid(source_name)), tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID);
p = pa_proplist_new();
@@ -1874,6 +2006,24 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
}
}
+ if (c->version >= 14) {
+
+ if (pa_tagstruct_get_boolean(t, &early_requests) < 0) {
+ protocol_error(c);
+ pa_proplist_free(p);
+ return;
+ }
+ }
+
+ if (c->version >= 15) {
+
+ if (pa_tagstruct_get_boolean(t, &dont_inhibit_auto_suspend) < 0) {
+ protocol_error(c);
+ pa_proplist_free(p);
+ return;
+ }
+ }
+
if (!pa_tagstruct_eof(t)) {
protocol_error(c);
pa_proplist_free(p);
@@ -1914,9 +2064,10 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
(fix_rate ? PA_SOURCE_OUTPUT_FIX_RATE : 0) |
(fix_channels ? PA_SOURCE_OUTPUT_FIX_CHANNELS : 0) |
(no_move ? PA_SOURCE_OUTPUT_DONT_MOVE : 0) |
- (variable_rate ? PA_SOURCE_OUTPUT_VARIABLE_RATE : 0);
+ (variable_rate ? PA_SOURCE_OUTPUT_VARIABLE_RATE : 0) |
+ (dont_inhibit_auto_suspend ? PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND : 0);
- s = record_stream_new(c, source, &ss, &map, peak_detect, &maxlength, &fragment_size, flags, p, adjust_latency, direct_on_input);
+ s = record_stream_new(c, source, &ss, &map, peak_detect, &maxlength, &fragment_size, flags, p, adjust_latency, direct_on_input, early_requests);
pa_proplist_free(p);
CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID);
@@ -1953,7 +2104,7 @@ static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
int ret;
@@ -1972,11 +2123,11 @@ static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t
pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */
}
-static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const void*cookie;
pa_tagstruct *reply;
- pa_bool_t shm_on_remote, do_shm;
+ pa_bool_t shm_on_remote = FALSE, do_shm;
pa_native_connection_assert_ref(c);
pa_assert(t);
@@ -2071,6 +2222,7 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t
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
@@ -2080,6 +2232,7 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t
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);
@@ -2103,7 +2256,7 @@ static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t
#endif
}
-static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const char *name = NULL;
pa_proplist *p;
@@ -2143,7 +2296,7 @@ static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const char *name;
uint32_t idx = PA_IDXSET_INVALID;
@@ -2158,7 +2311,7 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
if (command == PA_COMMAND_LOOKUP_SINK) {
pa_sink *sink;
@@ -2181,7 +2334,7 @@ static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uin
}
}
-static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
playback_stream *s;
@@ -2203,7 +2356,7 @@ static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC
pa_asyncmsgq_post(s->sink_input->sink->asyncmsgq, PA_MSGOBJECT(s->sink_input), SINK_INPUT_MESSAGE_DRAIN, PA_UINT_TO_PTR(tag), 0, NULL, NULL);
}
-static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_tagstruct *reply;
const pa_mempool_stat *stat;
@@ -2225,11 +2378,11 @@ static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t
pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->allocated_size));
pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->n_accumulated));
pa_tagstruct_putu32(reply, (uint32_t) pa_atomic_load(&stat->accumulated_size));
- pa_tagstruct_putu32(reply, pa_scache_total_size(c->protocol->core));
+ pa_tagstruct_putu32(reply, (uint32_t) pa_scache_total_size(c->protocol->core));
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_playback_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_tagstruct *reply;
playback_stream *s;
@@ -2275,7 +2428,7 @@ static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_tagstruct *reply;
record_stream *s;
@@ -2307,7 +2460,7 @@ static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
upload_stream *s;
uint32_t length;
@@ -2349,7 +2502,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
if (!(name = pa_proplist_gets(p, PA_PROP_EVENT_ID)))
name = pa_proplist_gets(p, PA_PROP_MEDIA_NAME);
- CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
s = upload_stream_new(c, &ss, &map, name, length, p);
pa_proplist_free(p);
@@ -2362,7 +2515,7 @@ static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_finish_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t channel;
upload_stream *s;
@@ -2391,7 +2544,7 @@ static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
upload_stream_unlink(s);
}
-static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t sink_index;
pa_volume_t volume;
@@ -2414,8 +2567,10 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui
return;
}
- CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
- CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !sink_name || pa_namereg_is_valid_name(sink_name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, sink_index == PA_INVALID_INDEX || !sink_name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !sink_name || sink_index == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
if (sink_index != PA_INVALID_INDEX)
sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index);
@@ -2451,7 +2606,7 @@ static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_remove_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const char *name;
@@ -2465,7 +2620,7 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, name && pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
if (pa_scache_remove_item(c->protocol->core, name) < 0) {
pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY);
@@ -2509,8 +2664,8 @@ static void sink_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_sin
PA_TAG_SAMPLE_SPEC, &fixed_ss,
PA_TAG_CHANNEL_MAP, &sink->channel_map,
PA_TAG_U32, sink->module ? sink->module->index : PA_INVALID_INDEX,
- PA_TAG_CVOLUME, pa_sink_get_volume(sink),
- PA_TAG_BOOLEAN, pa_sink_get_mute(sink),
+ PA_TAG_CVOLUME, pa_sink_get_volume(sink, FALSE),
+ PA_TAG_BOOLEAN, pa_sink_get_mute(sink, FALSE),
PA_TAG_U32, sink->monitor_source ? sink->monitor_source->index : PA_INVALID_INDEX,
PA_TAG_STRING, sink->monitor_source ? sink->monitor_source->name : NULL,
PA_TAG_USEC, pa_sink_get_latency(sink),
@@ -2540,8 +2695,8 @@ static void source_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
PA_TAG_SAMPLE_SPEC, &fixed_ss,
PA_TAG_CHANNEL_MAP, &source->channel_map,
PA_TAG_U32, source->module ? source->module->index : PA_INVALID_INDEX,
- PA_TAG_CVOLUME, pa_source_get_volume(source),
- PA_TAG_BOOLEAN, pa_source_get_mute(source),
+ PA_TAG_CVOLUME, pa_source_get_volume(source, FALSE),
+ PA_TAG_BOOLEAN, pa_source_get_mute(source, FALSE),
PA_TAG_U32, source->monitor_of ? source->monitor_of->index : PA_INVALID_INDEX,
PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL,
PA_TAG_USEC, pa_source_get_latency(source),
@@ -2577,7 +2732,7 @@ static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) {
pa_tagstruct_putu32(t, module->index);
pa_tagstruct_puts(t, module->name);
pa_tagstruct_puts(t, module->argument);
- pa_tagstruct_putu32(t, module->n_used);
+ pa_tagstruct_putu32(t, (uint32_t) module->n_used);
pa_tagstruct_put_boolean(t, module->auto_unload);
}
@@ -2597,7 +2752,7 @@ static void sink_input_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t,
pa_tagstruct_putu32(t, s->sink->index);
pa_tagstruct_put_sample_spec(t, &fixed_ss);
pa_tagstruct_put_channel_map(t, &s->channel_map);
- pa_tagstruct_put_cvolume(t, &s->volume);
+ pa_tagstruct_put_cvolume(t, pa_sink_input_get_volume(s));
pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s, &sink_latency));
pa_tagstruct_put_usec(t, sink_latency);
pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s)));
@@ -2650,7 +2805,7 @@ static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
pa_tagstruct_put_usec(t, e->memchunk.memblock ? pa_bytes_to_usec(e->memchunk.length, &e->sample_spec) : 0);
pa_tagstruct_put_sample_spec(t, &fixed_ss);
pa_tagstruct_put_channel_map(t, &e->channel_map);
- pa_tagstruct_putu32(t, e->memchunk.length);
+ pa_tagstruct_putu32(t, (uint32_t) e->memchunk.length);
pa_tagstruct_put_boolean(t, e->lazy);
pa_tagstruct_puts(t, e->filename);
@@ -2658,7 +2813,7 @@ static void scache_fill_tagstruct(pa_native_connection *c, pa_tagstruct *t, pa_s
pa_tagstruct_put_proplist(t, e->proplist);
}
-static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
pa_sink *sink = NULL;
@@ -2668,7 +2823,7 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u
pa_sink_input *si = NULL;
pa_source_output *so = NULL;
pa_scache_entry *sce = NULL;
- const char *name;
+ const char *name = NULL;
pa_tagstruct *reply;
pa_native_connection_assert_ref(c);
@@ -2686,7 +2841,10 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
if (command == PA_COMMAND_GET_SINK_INFO) {
if (idx != PA_INVALID_INDEX)
@@ -2737,7 +2895,7 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_idxset *i;
uint32_t idx;
@@ -2797,7 +2955,7 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_tagstruct *reply;
char txt[256];
@@ -2847,7 +3005,7 @@ static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint3
pa_pstream_send_tagstruct(c->pstream, t);
}
-static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_subscription_mask_t m;
@@ -2876,7 +3034,7 @@ static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint
}
static void command_set_volume(
- PA_GCC_UNUSED pa_pdispatch *pd,
+ pa_pdispatch *pd,
uint32_t command,
uint32_t tag,
pa_tagstruct *t,
@@ -2903,7 +3061,10 @@ static void command_set_volume(
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID);
switch (command) {
@@ -2943,7 +3104,7 @@ static void command_set_volume(
}
static void command_set_mute(
- PA_GCC_UNUSED pa_pdispatch *pd,
+ pa_pdispatch *pd,
uint32_t command,
uint32_t tag,
pa_tagstruct *t,
@@ -2970,7 +3131,10 @@ static void command_set_mute(
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
switch (command) {
@@ -3011,7 +3175,7 @@ static void command_set_mute(
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
pa_bool_t b;
@@ -3034,10 +3198,14 @@ static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_
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);
}
-static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_trigger_or_flush_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
playback_stream *s;
@@ -3077,7 +3245,7 @@ static void command_trigger_or_flush_or_prebuf_playback_stream(PA_GCC_UNUSED pa_
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
record_stream *s;
@@ -3102,7 +3270,7 @@ static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UN
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
record_stream *s;
@@ -3142,7 +3310,7 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
if (command == PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR) {
playback_stream *s;
- pa_bool_t adjust_latency = FALSE;
+ pa_bool_t adjust_latency = FALSE, early_requests = FALSE;
s = pa_idxset_get_by_index(c->output_streams, idx);
CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY);
@@ -3156,12 +3324,13 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
PA_TAG_U32, &minreq,
PA_TAG_INVALID) < 0 ||
(c->version >= 13 && pa_tagstruct_get_boolean(t, &adjust_latency) < 0) ||
+ (c->version >= 14 && pa_tagstruct_get_boolean(t, &early_requests) < 0) ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
}
- fix_playback_buffer_attr_pre(s, adjust_latency, &maxlength, &tlength, &prebuf, &minreq);
+ fix_playback_buffer_attr_pre(s, adjust_latency, early_requests, &maxlength, &tlength, &prebuf, &minreq);
pa_memblockq_set_maxlength(s->memblockq, maxlength);
pa_memblockq_set_tlength(s->memblockq, tlength);
pa_memblockq_set_prebuf(s->memblockq, prebuf);
@@ -3179,7 +3348,7 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
} else {
record_stream *s;
- pa_bool_t adjust_latency = FALSE;
+ pa_bool_t adjust_latency = FALSE, early_requests = FALSE;
pa_assert(command == PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR);
s = pa_idxset_get_by_index(c->record_streams, idx);
@@ -3191,12 +3360,13 @@ static void command_set_stream_buffer_attr(pa_pdispatch *pd, uint32_t command, u
PA_TAG_U32, &fragsize,
PA_TAG_INVALID) < 0 ||
(c->version >= 13 && pa_tagstruct_get_boolean(t, &adjust_latency) < 0) ||
+ (c->version >= 14 && pa_tagstruct_get_boolean(t, &early_requests) < 0) ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
}
- fix_record_buffer_attr_pre(s, adjust_latency, &maxlength, &fragsize);
+ fix_record_buffer_attr_pre(s, adjust_latency, early_requests, &maxlength, &fragsize);
pa_memblockq_set_maxlength(s->memblockq, maxlength);
fix_record_buffer_attr_post(s, &maxlength, &fragsize);
@@ -3387,7 +3557,7 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t
if (!z)
break;
- changed += pa_proplist_unset(p, z) >= 0;
+ changed += (unsigned) (pa_proplist_unset(p, z) >= 0);
pa_xfree(z);
}
@@ -3413,7 +3583,7 @@ static void command_remove_proplist(pa_pdispatch *pd, uint32_t command, uint32_t
}
}
-static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const char *s;
@@ -3427,13 +3597,13 @@ static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, u
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, !s || (*s && pa_utf8_valid(s)), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !s || pa_namereg_is_valid_name(s), tag, PA_ERR_INVALID);
pa_namereg_set_default(c->protocol->core, s, command == PA_COMMAND_SET_DEFAULT_SOURCE ? PA_NAMEREG_SOURCE : PA_NAMEREG_SINK);
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
const char *name;
@@ -3473,7 +3643,7 @@ static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t com
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
@@ -3521,7 +3691,7 @@ static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint3
pa_native_connection_unref(c);
}
-static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_module *m;
const char *name, *argument;
@@ -3551,7 +3721,7 @@ static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED ui
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx;
pa_module *m;
@@ -3573,7 +3743,7 @@ static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED
pa_pstream_send_simple_ack(c->pstream, tag);
}
-static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_add_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const char *name, *module, *argument;
uint32_t type;
@@ -3608,7 +3778,7 @@ static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED u
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_remove_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const char *name = NULL;
uint32_t type, idx = PA_IDXSET_INVALID;
@@ -3644,12 +3814,12 @@ static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e)
pa_tagstruct_putu32(t, e->index);
pa_tagstruct_puts(t, e->name);
- pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1);
+ pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0U : 1U);
pa_tagstruct_puts(t, e->module);
pa_tagstruct_puts(t, e->argument);
}
-static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_autoload_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
const pa_autoload_entry *a = NULL;
uint32_t type, idx;
@@ -3683,7 +3853,7 @@ static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNU
pa_pstream_send_tagstruct(c->pstream, reply);
}
-static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
+static void command_get_autoload_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
pa_tagstruct *reply;
@@ -3713,14 +3883,14 @@ static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GC
static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
pa_native_connection *c = PA_NATIVE_CONNECTION(userdata);
uint32_t idx = PA_INVALID_INDEX, idx_device = PA_INVALID_INDEX;
- const char *name = NULL;
+ const char *name_device = NULL;
pa_native_connection_assert_ref(c);
pa_assert(t);
if (pa_tagstruct_getu32(t, &idx) < 0 ||
pa_tagstruct_getu32(t, &idx_device) < 0 ||
- pa_tagstruct_gets(t, &name) < 0 ||
+ pa_tagstruct_gets(t, &name_device) < 0 ||
!pa_tagstruct_eof(t)) {
protocol_error(c);
return;
@@ -3728,7 +3898,11 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID);
- CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID);
+
+ CHECK_VALIDITY(c->pstream, !name_device || pa_namereg_is_valid_name(name_device), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx_device != PA_INVALID_INDEX || name_device, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx_device == PA_INVALID_INDEX || !name_device, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name_device || idx_device == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
if (command == PA_COMMAND_MOVE_SINK_INPUT) {
pa_sink_input *si = NULL;
@@ -3739,7 +3913,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
if (idx_device != PA_INVALID_INDEX)
sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx_device);
else
- sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1);
+ sink = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SINK, 1);
CHECK_VALIDITY(c->pstream, si && sink, tag, PA_ERR_NOENTITY);
@@ -3758,7 +3932,7 @@ static void command_move_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag
if (idx_device != PA_INVALID_INDEX)
source = pa_idxset_get_by_index(c->protocol->core->sources, idx_device);
else
- source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1);
+ source = pa_namereg_get(c->protocol->core, name_device, PA_NAMEREG_SOURCE, 1);
CHECK_VALIDITY(c->pstream, so && source, tag, PA_ERR_NOENTITY);
@@ -3789,7 +3963,10 @@ static void command_suspend(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
if (command == PA_COMMAND_SUSPEND_SINK) {
@@ -3862,7 +4039,10 @@ static void command_extension(pa_pdispatch *pd, uint32_t command, uint32_t tag,
}
CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS);
- CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || !*name || pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || pa_utf8_valid(name), tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, idx == PA_INVALID_INDEX || !name, tag, PA_ERR_INVALID);
+ CHECK_VALIDITY(c->pstream, !name || idx == PA_INVALID_INDEX, tag, PA_ERR_INVALID);
if (idx != PA_INVALID_INDEX)
m = pa_idxset_get_by_index(c->protocol->core->modules, idx);
@@ -3912,6 +4092,8 @@ static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t o
return;
}
+/* pa_log("got %lu bytes", (unsigned long) chunk->length); */
+
if (playback_stream_isinstance(stream)) {
playback_stream *ps = PLAYBACK_STREAM(stream);
@@ -4299,7 +4481,7 @@ int pa_native_options_parse(pa_native_options *o, pa_core *c, pa_modargs *ma) {
if ((acl = pa_modargs_get_value(ma, "auth-ip-acl", NULL))) {
pa_ip_acl *ipa;
- if (!(o->auth_ip_acl = pa_ip_acl_new(acl))) {
+ if (!(ipa = pa_ip_acl_new(acl))) {
pa_log("Failed to parse IP ACL '%s'", acl);
return -1;
}
diff --git a/src/pulsecore/protocol-simple.c b/src/pulsecore/protocol-simple.c
index 78874bb9..743bf2ee 100644
--- a/src/pulsecore/protocol-simple.c
+++ b/src/pulsecore/protocol-simple.c
@@ -159,7 +159,7 @@ static int do_read(connection *c) {
connection_assert_ref(c);
- if (!c->sink_input || (l = pa_atomic_load(&c->playback.missing)) <= 0)
+ if (!c->sink_input || (l = (size_t) pa_atomic_load(&c->playback.missing)) <= 0)
return 0;
if (c->playback.current_memblock) {
@@ -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);
@@ -197,12 +197,12 @@ static int do_read(connection *c) {
chunk.memblock = c->playback.current_memblock;
chunk.index = c->playback.memblock_index;
- chunk.length = r;
+ chunk.length = (size_t) r;
- c->playback.memblock_index += r;
+ c->playback.memblock_index += (size_t) r;
pa_asyncmsgq_post(c->sink_input->sink->asyncmsgq, PA_MSGOBJECT(c->sink_input), SINK_INPUT_MESSAGE_POST_DATA, NULL, 0, &chunk, NULL);
- pa_atomic_sub(&c->playback.missing, r);
+ pa_atomic_sub(&c->playback.missing, (int) r);
return 0;
}
@@ -240,7 +240,7 @@ static int do_write(connection *c) {
return -1;
}
- pa_memblockq_drop(c->output_memblockq, r);
+ pa_memblockq_drop(c->output_memblockq, (size_t) r);
return 0;
}
@@ -377,7 +377,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
m = pa_memblockq_pop_missing(c->input_memblockq);
if (m > 0)
- if (pa_atomic_add(&c->playback.missing, m) <= 0)
+ if (pa_atomic_add(&c->playback.missing, (int) m) <= 0)
pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(c), CONNECTION_MESSAGE_REQUEST_DATA, NULL, 0, NULL, NULL);
return 0;
@@ -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;
@@ -546,7 +548,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
pa_sink_input_set_requested_latency(c->sink_input, DEFAULT_SINK_LATENCY);
- l = (size_t) (pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS);
+ l = (size_t) ((double) pa_bytes_per_second(&o->sample_spec)*PLAYBACK_BUFFER_SECONDS);
c->input_memblockq = pa_memblockq_new(
0,
l,
@@ -558,7 +560,7 @@ void pa_simple_protocol_connect(pa_simple_protocol *p, pa_iochannel *io, pa_simp
NULL);
pa_iochannel_socket_set_rcvbuf(io, l);
- pa_atomic_store(&c->playback.missing, pa_memblockq_missing(c->input_memblockq));
+ pa_atomic_store(&c->playback.missing, (int) pa_memblockq_missing(c->input_memblockq));
pa_sink_input_put(c->sink_input);
}
@@ -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/pstream.c b/src/pulsecore/pstream.c
index 6b1af67b..7ff8edc9 100644
--- a/src/pulsecore/pstream.c
+++ b/src/pulsecore/pstream.c
@@ -283,7 +283,7 @@ pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_mempool *poo
return p;
}
-static void item_free(void *item, PA_GCC_UNUSED void *q) {
+static void item_free(void *item, void *q) {
struct item_info *i = item;
pa_assert(i);
@@ -488,7 +488,7 @@ static void prepare_next_write_item(pa_pstream *p) {
pa_assert(p->write.current->packet);
p->write.data = p->write.current->packet->data;
- p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->packet->length);
+ p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->packet->length);
} else if (p->write.current->type == PA_PSTREAM_ITEM_SHMRELEASE) {
@@ -511,7 +511,7 @@ static void prepare_next_write_item(pa_pstream *p) {
p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = htonl((uint32_t) (((uint64_t) p->write.current->offset) >> 32));
p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = htonl((uint32_t) ((uint64_t) p->write.current->offset));
- flags = p->write.current->seek_mode & PA_FLAG_SEEKMASK;
+ flags = (uint32_t) (p->write.current->seek_mode & PA_FLAG_SEEKMASK);
if (p->use_shm) {
uint32_t block_id, shm_id;
@@ -542,7 +542,7 @@ static void prepare_next_write_item(pa_pstream *p) {
}
if (send_payload) {
- p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->chunk.length);
+ p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl((uint32_t) p->write.current->chunk.length);
p->write.memchunk = p->write.current->chunk;
pa_memblock_ref(p->write.memchunk.memblock);
p->write.data = NULL;
@@ -607,7 +607,7 @@ static int do_write(pa_pstream *p) {
if (release_memblock)
pa_memblock_release(release_memblock);
- p->write.index += r;
+ p->write.index += (size_t) r;
if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE + ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) {
pa_assert(p->write.current);
@@ -675,7 +675,7 @@ static int do_read(pa_pstream *p) {
if (release_memblock)
pa_memblock_release(release_memblock);
- p->read.index += r;
+ p->read.index += (size_t) r;
if (p->read.index == PA_PSTREAM_DESCRIPTOR_SIZE) {
uint32_t flags, length, channel;
@@ -769,7 +769,7 @@ static int do_read(pa_pstream *p) {
if (p->read.memblock && p->recieve_memblock_callback) {
/* Is this memblock data? Than pass it to the user */
- l = (p->read.index - r) < PA_PSTREAM_DESCRIPTOR_SIZE ? p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE : (size_t) r;
+ l = (p->read.index - (size_t) r) < PA_PSTREAM_DESCRIPTOR_SIZE ? (size_t) (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE) : (size_t) r;
if (l > 0) {
pa_memchunk chunk;
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index c82f4c1e..b2d512c8 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -373,7 +373,7 @@ size_t pa_resampler_max_block_size(pa_resampler *r) {
/* We deduce the "largest" sample spec we're using during the
* conversion */
- ss.channels = PA_MAX(r->i_ss.channels, r->o_ss.channels);
+ ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));
/* We silently assume that the format enum is ordered by size */
ss.format = PA_MAX(r->i_ss.format, r->o_ss.format);
@@ -642,7 +642,7 @@ static void calc_map_table(pa_resampler *r) {
if (n > 0)
for (ic = 0; ic < r->i_ss.channels; ic++)
if (on_left(r->i_cm.map[ic])) {
- r->map_table[oc][ic] = 1.0 / n;
+ r->map_table[oc][ic] = 1.0f / (float) n;
ic_connected[ic] = TRUE;
}
@@ -663,7 +663,7 @@ static void calc_map_table(pa_resampler *r) {
if (n > 0)
for (ic = 0; ic < r->i_ss.channels; ic++)
if (on_right(r->i_cm.map[ic])) {
- r->map_table[oc][ic] = 1.0 / n;
+ r->map_table[oc][ic] = 1.0f / (float) n;
ic_connected[ic] = TRUE;
}
@@ -684,7 +684,7 @@ static void calc_map_table(pa_resampler *r) {
if (n > 0) {
for (ic = 0; ic < r->i_ss.channels; ic++)
if (on_center(r->i_cm.map[ic])) {
- r->map_table[oc][ic] = 1.0 / n;
+ r->map_table[oc][ic] = 1.0f / (float) n;
ic_connected[ic] = TRUE;
}
} else {
@@ -701,7 +701,7 @@ static void calc_map_table(pa_resampler *r) {
if (n > 0)
for (ic = 0; ic < r->i_ss.channels; ic++)
if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
- r->map_table[oc][ic] = 1.0 / n;
+ r->map_table[oc][ic] = 1.0f / (float) n;
ic_connected[ic] = TRUE;
}
@@ -716,7 +716,11 @@ static void calc_map_table(pa_resampler *r) {
* channels for LFE. */
for (ic = 0; ic < r->i_ss.channels; ic++) {
- r->map_table[oc][ic] = 1.0 / r->i_ss.channels;
+
+ if (!(r->flags & PA_RESAMPLER_NO_LFE))
+ r->map_table[oc][ic] = 1.0f / (float) r->i_ss.channels;
+ else
+ r->map_table[oc][ic] = 0;
/* Please note that a channel connected to LFE
* doesn't really count as connected. */
@@ -763,12 +767,12 @@ static void calc_map_table(pa_resampler *r) {
for (ic = 0; ic < r->i_ss.channels; ic++) {
if (ic_connected[ic]) {
- r->map_table[oc][ic] *= .9;
+ r->map_table[oc][ic] *= .9f;
continue;
}
if (on_left(r->i_cm.map[ic]))
- r->map_table[oc][ic] = .1 / ic_unconnected_left;
+ r->map_table[oc][ic] = .1f / (float) ic_unconnected_left;
}
}
}
@@ -788,12 +792,12 @@ static void calc_map_table(pa_resampler *r) {
for (ic = 0; ic < r->i_ss.channels; ic++) {
if (ic_connected[ic]) {
- r->map_table[oc][ic] *= .9;
+ r->map_table[oc][ic] *= .9f;
continue;
}
if (on_right(r->i_cm.map[ic]))
- r->map_table[oc][ic] = .1 / ic_unconnected_right;
+ r->map_table[oc][ic] = .1f / (float) ic_unconnected_right;
}
}
}
@@ -814,12 +818,12 @@ static void calc_map_table(pa_resampler *r) {
for (ic = 0; ic < r->i_ss.channels; ic++) {
if (ic_connected[ic]) {
- r->map_table[oc][ic] *= .9;
+ r->map_table[oc][ic] *= .9f;
continue;
}
if (on_center(r->i_cm.map[ic])) {
- r->map_table[oc][ic] = .1 / ic_unconnected_center;
+ r->map_table[oc][ic] = .1f / (float) ic_unconnected_center;
mixed_in = TRUE;
}
}
@@ -840,18 +844,18 @@ static void calc_map_table(pa_resampler *r) {
for (ic = 0; ic < r->i_ss.channels; ic++) {
if (ic_connected[ic]) {
- r->map_table[oc][ic] *= .75;
+ r->map_table[oc][ic] *= .75f;
continue;
}
if (on_center(r->i_cm.map[ic]))
- r->map_table[oc][ic] = .375 / ic_unconnected_center;
+ r->map_table[oc][ic] = .375f / (float) ic_unconnected_center;
}
}
}
}
- if (ic_unconnected_lfe > 0) {
+ if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
/* OK, so there is an unconnected LFE channel. Let's mix
* it into all channels, with factor 0.375 */
@@ -862,7 +866,7 @@ static void calc_map_table(pa_resampler *r) {
continue;
for (oc = 0; oc < r->o_ss.channels; oc++)
- r->map_table[oc][ic] = 0.375 / ic_unconnected_lfe;
+ r->map_table[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
}
}
}
@@ -905,7 +909,7 @@ static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input)
if (!r->to_work_format_func || !input->length)
return input;
- n_samples = (input->length / r->i_fz) * r->i_ss.channels;
+ n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
r->buf1.index = 0;
r->buf1.length = r->w_sz * n_samples;
@@ -974,7 +978,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
if (!r->map_required || !input->length)
return input;
- in_n_samples = input->length / r->w_sz;
+ in_n_samples = (unsigned) (input->length / r->w_sz);
n_frames = in_n_samples / r->i_ss.channels;
out_n_samples = n_frames * r->o_ss.channels;
@@ -994,8 +998,8 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
memset(dst, 0, r->buf2.length);
- o_skip = r->w_sz * r->o_ss.channels;
- i_skip = r->w_sz * r->i_ss.channels;
+ o_skip = (int) (r->w_sz * r->o_ss.channels);
+ i_skip = (int) (r->w_sz * r->i_ss.channels);
switch (r->work_format) {
case PA_SAMPLE_FLOAT32NE:
@@ -1013,7 +1017,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
(float*) dst + oc, o_skip,
(float*) dst + oc, o_skip,
(float*) src + ic, i_skip,
- n_frames,
+ (int) n_frames,
&one, &r->map_table[oc][ic]);
}
}
@@ -1037,7 +1041,7 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
(int16_t*) dst + oc, o_skip,
(int16_t*) dst + oc, o_skip,
(int16_t*) src + ic, i_skip,
- n_frames,
+ (int) n_frames,
&one, &one);
} else
@@ -1046,8 +1050,8 @@ static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
(int16_t*) dst + oc, o_skip,
(int16_t*) dst + oc, o_skip,
(int16_t*) src + ic, i_skip,
- n_frames,
- 1.0, r->map_table[oc][ic]);
+ (int) n_frames,
+ 1.0f, r->map_table[oc][ic]);
}
}
@@ -1077,8 +1081,8 @@ static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
if (!r->impl_resample || !input->length)
return input;
- in_n_samples = input->length / r->w_sz;
- in_n_frames = in_n_samples / r->o_ss.channels;
+ in_n_samples = (unsigned) (input->length / r->w_sz);
+ in_n_frames = (unsigned) (in_n_samples / r->o_ss.channels);
out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES;
out_n_samples = out_n_frames * r->o_ss.channels;
@@ -1112,8 +1116,8 @@ static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input
if (!r->from_work_format_func || !input->length)
return input;
- n_samples = input->length / r->w_sz;
- n_frames = n_samples / r->o_ss.channels;
+ n_samples = (unsigned) (input->length / r->w_sz);
+ n_frames = n_samples / r->o_ss.channels;
r->buf4.index = 0;
r->buf4.length = r->o_fz * n_frames;
@@ -1178,10 +1182,10 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un
memset(&data, 0, sizeof(data));
data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
- data.input_frames = in_n_frames;
+ data.input_frames = (long int) in_n_frames;
data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
- data.output_frames = *out_n_frames;
+ data.output_frames = (long int) *out_n_frames;
data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
data.end_of_input = 0;
@@ -1192,7 +1196,7 @@ static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, un
pa_memblock_release(input->memblock);
pa_memblock_release(output->memblock);
- *out_n_frames = data.output_frames_gen;
+ *out_n_frames = (unsigned) data.output_frames_gen;
}
static void libsamplerate_update_rates(pa_resampler *r) {
@@ -1354,7 +1358,7 @@ static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned
pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
oil_memcpy((uint8_t*) dst + fz * o_index,
- (uint8_t*) src + fz * j, fz);
+ (uint8_t*) src + fz * j, (int) fz);
}
pa_memblock_release(input->memblock);
@@ -1414,40 +1418,46 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
unsigned j;
j = ((r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate);
- j = j > r->peaks.i_counter ? j - r->peaks.i_counter : 0;
- if (j >= in_n_frames)
- break;
+ if (j > r->peaks.i_counter)
+ j -= r->peaks.i_counter;
+ else
+ j = 0;
pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
if (r->work_format == PA_SAMPLE_S16NE) {
unsigned i, c;
- int16_t *s = (int16_t*) ((uint8_t*) src + fz * j);
+ int16_t *s = (int16_t*) ((uint8_t*) src + fz * start);
int16_t *d = (int16_t*) ((uint8_t*) dst + fz * o_index);
- for (i = start; i <= j; i++)
+ for (i = start; i <= j && i < in_n_frames; i++)
+
for (c = 0; c < r->o_ss.channels; c++, s++) {
int16_t n;
- n = *s < 0 ? -*s : *s;
+ n = (int16_t) (*s < 0 ? -*s : *s);
- if (n > r->peaks.max_i[c])
+ if (PA_UNLIKELY(n > r->peaks.max_i[c]))
r->peaks.max_i[c] = n;
}
+ if (i >= in_n_frames)
+ break;
+
for (c = 0; c < r->o_ss.channels; c++, d++) {
- *d = r->peaks.max_i[c];
- r->peaks.max_i[c] = 0;
+ *d = r->peaks.max_i[c];
+ r->peaks.max_i[c] = 0;
}
+
} else {
unsigned i, c;
- float *s = (float*) ((uint8_t*) src + fz * j);
+ float *s = (float*) ((uint8_t*) src + fz * start);
float *d = (float*) ((uint8_t*) dst + fz * o_index);
pa_assert(r->work_format == PA_SAMPLE_FLOAT32NE);
- for (i = start; i <= j; i++)
+ for (i = start; i <= j && i < in_n_frames; i++)
for (c = 0; c < r->o_ss.channels; c++, s++) {
float n = fabsf(*s);
@@ -1455,13 +1465,16 @@ static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned i
r->peaks.max_f[c] = n;
}
+ if (i >= in_n_frames)
+ break;
+
for (c = 0; c < r->o_ss.channels; c++, d++) {
*d = r->peaks.max_f[c];
r->peaks.max_f[c] = 0;
}
}
- start = j+1;
+ start = j;
}
pa_memblock_release(input->memblock);
@@ -1523,7 +1536,7 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned
p = pa_memblock_acquire(b);
/* Copy the remaining data into it */
- l = r->ffmpeg.buf[c].length;
+ l = (unsigned) r->ffmpeg.buf[c].length;
if (r->ffmpeg.buf[c].memblock) {
t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
memcpy(p, t, l);
@@ -1543,18 +1556,18 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned
pa_memblock_release(input->memblock);
/* Calculate the resulting number of frames */
- in = in_n_frames + l / sizeof(int16_t);
+ in = (unsigned) in_n_frames + l / (unsigned) sizeof(int16_t);
/* Allocate buffer for the result */
w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
q = pa_memblock_acquire(w);
/* Now, resample */
- used_frames = av_resample(r->ffmpeg.state,
- q, p,
- &consumed_frames,
- in, *out_n_frames,
- c >= (unsigned) r->o_ss.channels-1);
+ used_frames = (unsigned) av_resample(r->ffmpeg.state,
+ q, p,
+ &consumed_frames,
+ (int) in, (int) *out_n_frames,
+ c >= (unsigned) (r->o_ss.channels-1));
pa_memblock_release(b);
@@ -1562,8 +1575,8 @@ static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned
pa_assert(consumed_frames <= (int) in);
if (consumed_frames < (int) in) {
r->ffmpeg.buf[c].memblock = b;
- r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t);
- r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t);
+ r->ffmpeg.buf[c].index = (size_t) consumed_frames * sizeof(int16_t);
+ r->ffmpeg.buf[c].length = (size_t) (in - (unsigned) consumed_frames) * sizeof(int16_t);
} else
pa_memblock_unref(b);
@@ -1605,7 +1618,7 @@ static int ffmpeg_init(pa_resampler *r) {
* internally only uses these hardcoded values, so let's use them
* here for now as well until ffmpeg makes this configurable. */
- if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8)))
+ if (!(r->ffmpeg.state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8)))
return -1;
r->impl_free = ffmpeg_free;
diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h
index 5e302a9b..87110cc2 100644
--- a/src/pulsecore/resampler.h
+++ b/src/pulsecore/resampler.h
@@ -49,9 +49,10 @@ typedef enum pa_resample_method {
} pa_resample_method_t;
typedef enum pa_resample_flags {
- PA_RESAMPLER_VARIABLE_RATE = 1,
- PA_RESAMPLER_NO_REMAP = 2, /* implies NO_REMIX */
- PA_RESAMPLER_NO_REMIX = 4
+ PA_RESAMPLER_VARIABLE_RATE = 0x0001U,
+ PA_RESAMPLER_NO_REMAP = 0x0002U, /* implies NO_REMIX */
+ PA_RESAMPLER_NO_REMIX = 0x0004U,
+ PA_RESAMPLER_NO_LFE = 0x0008U
} pa_resample_flags_t;
pa_resampler* pa_resampler_new(
diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h
index 705de48f..aa2cdace 100644
--- a/src/pulsecore/rtclock.h
+++ b/src/pulsecore/rtclock.h
@@ -23,6 +23,7 @@
***/
#include <pulsecore/macro.h>
+#include <pulse/sample.h>
struct timeval;
diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c
index a67a5516..543262bc 100644
--- a/src/pulsecore/rtpoll.c
+++ b/src/pulsecore/rtpoll.c
@@ -394,7 +394,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) {
#endif
#endif
- r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (timeout.tv_sec*1000) + (timeout.tv_usec / 1000) : -1);
+ r = poll(p->pollfd, p->n_pollfd_used, (!wait || p->quit || p->timer_enabled) ? (int) ((timeout.tv_sec*1000) + (timeout.tv_usec / 1000)) : -1);
if (r < 0) {
if (errno == EAGAIN || errno == EINTR)
diff --git a/src/pulsecore/rtsig.c b/src/pulsecore/rtsig.c
index 4df217c3..4cd6aa8f 100644
--- a/src/pulsecore/rtsig.c
+++ b/src/pulsecore/rtsig.c
@@ -40,7 +40,7 @@ static void _free_rtsig(void *p) {
pa_rtsig_put(PA_PTR_TO_INT(p));
}
-PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two(SIGRTMAX-SIGRTMIN+1), NULL);
+PA_STATIC_FLIST_DECLARE(rtsig_flist, pa_make_power_of_two((unsigned) (SIGRTMAX-SIGRTMIN+1)), NULL);
PA_STATIC_TLS_DECLARE(rtsig_tls, _free_rtsig);
static pa_atomic_t rtsig_current = PA_ATOMIC_INIT(-1);
diff --git a/src/pulsecore/sample-util.c b/src/pulsecore/sample-util.c
index b42b79d1..9f0f795c 100644
--- a/src/pulsecore/sample-util.c
+++ b/src/pulsecore/sample-util.c
@@ -31,6 +31,8 @@
#include <liboil/liboilfuncs.h>
#include <liboil/liboil.h>
+#include <pulse/timeval.h>
+
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/g711.h>
@@ -85,7 +87,6 @@ static uint8_t silence_byte(pa_sample_format_t format) {
default:
pa_assert_not_reached();
}
- return 0;
}
void* pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) {
@@ -97,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 = 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] = 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(
@@ -160,7 +167,8 @@ size_t pa_mix(
pa_cvolume full_volume;
unsigned k;
- size_t d = 0;
+ unsigned z;
+ void *end;
pa_assert(streams);
pa_assert(data);
@@ -170,45 +178,46 @@ size_t pa_mix(
if (!volume)
volume = pa_cvolume_reset(&full_volume, spec->channels);
+ if (mute || pa_cvolume_is_muted(volume) || nstreams <= 0) {
+ pa_silence_memory(data, length, spec);
+ return length;
+ }
+
for (k = 0; k < nstreams; k++)
streams[k].ptr = (uint8_t*) pa_memblock_acquire(streams[k].chunk.memblock) + streams[k].chunk.index;
+ for (z = 0; z < nstreams; z++)
+ if (length > streams[z].chunk.length)
+ length = streams[z].chunk.length;
+
+ end = (uint8_t*) data + length;
+
switch (spec->format) {
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);
- for (d = 0;; d += sizeof(int16_t)) {
+ while (data < end) {
int32_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
int32_t v, cv = m->linear[channel].i;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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 = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
- sum = (sum * linear[channel]) / 0x10000;
*((int16_t*) data) = (int16_t) sum;
data = (uint8_t*) data + sizeof(int16_t);
@@ -222,38 +231,28 @@ 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);
- for (d = 0;; d += sizeof(int16_t)) {
+ while (data < end) {
int32_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
int32_t v, cv = m->linear[channel].i;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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 = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
- sum = (sum * linear[channel]) / 0x10000;
*((int16_t*) data) = PA_INT16_SWAP((int16_t) sum);
data = (uint8_t*) data + sizeof(int16_t);
@@ -267,39 +266,29 @@ 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);
- for (d = 0;; d += sizeof(int32_t)) {
+ while (data < end) {
int64_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
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(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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 = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
- sum = (sum * linear[channel]) / 0x10000;
*((int32_t*) data) = (int32_t) sum;
data = (uint8_t*) data + sizeof(int32_t);
@@ -313,39 +302,29 @@ 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);
- for (d = 0;; d += sizeof(int32_t)) {
+ while (data < end) {
int64_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
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(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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 = PA_CLAMP_UNLIKELY(sum, -0x80000000LL, 0x7FFFFFFFLL);
- sum = (sum * linear[channel]) / 0x10000;
*((int32_t*) data) = PA_INT32_SWAP((int32_t) sum);
data = (uint8_t*) data + sizeof(int32_t);
@@ -359,37 +338,27 @@ 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);
- for (d = 0;; d ++) {
+ while (data < end) {
int32_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
int32_t v, cv = m->linear[channel].i;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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);
@@ -404,39 +373,29 @@ 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);
- for (d = 0;; d ++) {
+ while (data < end) {
int32_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
int32_t v, cv = m->linear[channel].i;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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 = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
- sum = (sum * linear[channel]) / 0x10000;
- *((uint8_t*) data) = (uint8_t) st_14linear2ulaw(sum >> 2);
+ *((uint8_t*) data) = (uint8_t) st_14linear2ulaw((int16_t) sum >> 2);
data = (uint8_t*) data + 1;
@@ -449,39 +408,29 @@ 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);
- for (d = 0;; d ++) {
+ while (data < end) {
int32_t sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
int32_t v, cv = m->linear[channel].i;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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 = PA_CLAMP_UNLIKELY(sum, -0x8000, 0x7FFF);
- sum = (sum * linear[channel]) / 0x10000;
- *((uint8_t*) data) = (uint8_t) st_13linear2alaw(sum >> 3);
+ *((uint8_t*) data) = (uint8_t) st_13linear2alaw((int16_t) sum >> 3);
data = (uint8_t*) data + 1;
@@ -494,37 +443,27 @@ 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);
- for (d = 0;; d += sizeof(float)) {
+ while (data < end) {
float sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
float v, cv = m->linear[channel].f;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || 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);
@@ -540,38 +479,27 @@ 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);
- for (d = 0;; d += sizeof(float)) {
+ while (data < end) {
float sum = 0;
unsigned i;
- if (PA_UNLIKELY(d >= length))
- goto finish;
-
for (i = 0; i < nstreams; i++) {
pa_mix_info *m = streams + i;
float v, cv = m->linear[channel].f;
- if (PA_UNLIKELY(d >= m->chunk.length))
- goto finish;
-
- if (PA_UNLIKELY(cv <= 0) || PA_UNLIKELY(!!mute) || PA_UNLIKELY(linear[channel] <= 0))
- v = 0;
- else {
- uint32_t z = *(uint32_t*) m->ptr;
- z = PA_UINT32_SWAP(z);
- v = *((float*) &z);
- v *= 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];
- *((uint32_t*) data) = PA_UINT32_SWAP(*(uint32_t*) &sum);
+ *((float*) data) = PA_FLOAT32_SWAP(sum);
data = (uint8_t*) data + sizeof(float);
@@ -583,16 +511,14 @@ size_t pa_mix(
}
default:
- pa_log_error("ERROR: Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format));
+ pa_log_error("Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format));
pa_assert_not_reached();
}
-finish:
-
for (k = 0; k < nstreams; k++)
pa_memblock_release(streams[k].chunk.memblock);
- return d;
+ return length;
}
@@ -624,14 +550,15 @@ void pa_volume_memchunk(
switch (spec->format) {
case PA_SAMPLE_S16NE: {
- int16_t *d;
- size_t n;
+ int16_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length/sizeof(int16_t); n > 0; d++, n--) {
+ e = (int16_t*) ptr + c->length/sizeof(int16_t);
+
+ for (channel = 0, d = ptr; d < e; d++) {
int32_t t;
t = (int32_t)(*d);
@@ -646,17 +573,18 @@ void pa_volume_memchunk(
}
case PA_SAMPLE_S16RE: {
- int16_t *d;
- size_t n;
+ int16_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length/sizeof(int16_t); n > 0; d++, n--) {
+ e = (int16_t*) ptr + c->length/sizeof(int16_t);
+
+ for (channel = 0, d = ptr; d < e; d++) {
int32_t t;
- t = (int32_t)(PA_INT16_SWAP(*d));
+ t = (int32_t) PA_INT16_SWAP(*d);
t = (t * linear[channel]) / 0x10000;
t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
*d = PA_INT16_SWAP((int16_t) t);
@@ -669,14 +597,15 @@ void pa_volume_memchunk(
}
case PA_SAMPLE_S32NE: {
- int32_t *d;
- size_t n;
+ int32_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length/sizeof(int32_t); n > 0; d++, n--) {
+ e = (int32_t*) ptr + c->length/sizeof(int32_t);
+
+ for (channel = 0, d = ptr; d < e; d++) {
int64_t t;
t = (int64_t)(*d);
@@ -691,17 +620,18 @@ void pa_volume_memchunk(
}
case PA_SAMPLE_S32RE: {
- int32_t *d;
- size_t n;
+ int32_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length/sizeof(int32_t); n > 0; d++, n--) {
+ e = (int32_t*) ptr + c->length/sizeof(int32_t);
+
+ for (channel = 0, d = ptr; d < e; d++) {
int64_t t;
- t = (int64_t)(PA_INT32_SWAP(*d));
+ t = (int64_t) PA_INT32_SWAP(*d);
t = (t * linear[channel]) / 0x10000;
t = PA_CLAMP_UNLIKELY(t, -0x80000000LL, 0x7FFFFFFFLL);
*d = PA_INT32_SWAP((int32_t) t);
@@ -714,14 +644,15 @@ void pa_volume_memchunk(
}
case PA_SAMPLE_U8: {
- uint8_t *d;
- size_t n;
+ uint8_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) {
+ e = (uint8_t*) ptr + c->length;
+
+ for (channel = 0, d = ptr; d < e; d++) {
int32_t t;
t = (int32_t) *d - 0x80;
@@ -736,20 +667,21 @@ void pa_volume_memchunk(
}
case PA_SAMPLE_ULAW: {
- uint8_t *d;
- size_t n;
+ uint8_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) {
+ e = (uint8_t*) ptr + c->length;
+
+ for (channel = 0, d = ptr; d < e; d++) {
int32_t t;
t = (int32_t) st_ulaw2linear16(*d);
t = (t * linear[channel]) / 0x10000;
t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
- *d = (uint8_t) st_14linear2ulaw(t >> 2);
+ *d = (uint8_t) st_14linear2ulaw((int16_t) t >> 2);
if (PA_UNLIKELY(++channel >= spec->channels))
channel = 0;
@@ -758,20 +690,21 @@ void pa_volume_memchunk(
}
case PA_SAMPLE_ALAW: {
- uint8_t *d;
- size_t n;
+ uint8_t *d, *e;
unsigned channel;
int32_t linear[PA_CHANNELS_MAX];
calc_linear_integer_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length; n > 0; d++, n--) {
+ e = (uint8_t*) ptr + c->length;
+
+ for (channel = 0, d = ptr; d < e; d++) {
int32_t t;
t = (int32_t) st_alaw2linear16(*d);
t = (t * linear[channel]) / 0x10000;
t = PA_CLAMP_UNLIKELY(t, -0x8000, 0x7FFF);
- *d = (uint8_t) st_13linear2alaw(t >> 3);
+ *d = (uint8_t) st_13linear2alaw((int16_t) t >> 3);
if (PA_UNLIKELY(++channel >= spec->channels))
channel = 0;
@@ -786,8 +719,8 @@ void pa_volume_memchunk(
unsigned channel;
d = ptr;
- skip = spec->channels * sizeof(float);
- n = c->length/sizeof(float)/spec->channels;
+ skip = (int) (spec->channels * sizeof(float));
+ n = (unsigned) (c->length/sizeof(float)/spec->channels);
for (channel = 0; channel < spec->channels; channel ++) {
float v, *t;
@@ -797,28 +730,26 @@ void pa_volume_memchunk(
v = (float) pa_sw_volume_to_linear(volume->values[channel]);
t = d + channel;
- oil_scalarmult_f32(t, skip, t, skip, &v, n);
+ oil_scalarmult_f32(t, skip, t, skip, &v, (int) n);
}
break;
}
case PA_SAMPLE_FLOAT32RE: {
- uint32_t *d;
- size_t n;
+ float *d, *e;
unsigned channel;
float linear[PA_CHANNELS_MAX];
calc_linear_float_volume(linear, volume);
- for (channel = 0, d = ptr, n = c->length/sizeof(float); n > 0; d++, n--) {
+ e = (float*) ptr + c->length/sizeof(float);
+
+ for (channel = 0, d = ptr; d < e; d++) {
float t;
- uint32_t z;
- z = PA_UINT32_SWAP(*d);
- t = *(float*) &z;
+ t = PA_FLOAT32_SWAP(*d);
t *= linear[channel];
- z = *(uint32_t*) &t;
- *d = PA_UINT32_SWAP(z);
+ *d = PA_FLOAT32_SWAP(t);
if (PA_UNLIKELY(++channel >= spec->channels))
channel = 0;
@@ -846,7 +777,7 @@ size_t pa_frame_align(size_t l, const pa_sample_spec *ss) {
return (l/fs) * fs;
}
-int pa_frame_aligned(size_t l, const pa_sample_spec *ss) {
+pa_bool_t pa_frame_aligned(size_t l, const pa_sample_spec *ss) {
size_t fs;
pa_assert(ss);
@@ -877,7 +808,7 @@ void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, u
d = (uint8_t*) dst + c * ss;
for (j = 0; j < n; j ++) {
- oil_memcpy(d, s, ss);
+ oil_memcpy(d, s, (int) ss);
s = (uint8_t*) s + ss;
d = (uint8_t*) d + fs;
}
@@ -905,7 +836,7 @@ void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss,
d = dst[c];
for (j = 0; j < n; j ++) {
- oil_memcpy(d, s, ss);
+ oil_memcpy(d, s, (int) ss);
s = (uint8_t*) s + fs;
d = (uint8_t*) d + ss;
}
@@ -1008,7 +939,7 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo
if (format == PA_SAMPLE_FLOAT32NE) {
float minus_one = -1.0, plus_one = 1.0;
- oil_clip_f32(d, dstr, s, sstr, n, &minus_one, &plus_one);
+ oil_clip_f32(d, (int) dstr, s, (int) sstr, (int) n, &minus_one, &plus_one);
} else {
pa_assert(format == PA_SAMPLE_FLOAT32RE);
@@ -1017,7 +948,7 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo
float f;
f = PA_FLOAT32_SWAP(*s);
- f = PA_CLAMP_UNLIKELY(f, -1.0, 1.0);
+ f = PA_CLAMP_UNLIKELY(f, -1.0f, 1.0f);
*d = PA_FLOAT32_SWAP(f);
s = (const float*) ((const uint8_t*) s + sstr);
@@ -1025,3 +956,34 @@ void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const vo
}
}
}
+
+/* Similar to pa_bytes_to_usec() but rounds up, not down */
+
+pa_usec_t pa_bytes_to_usec_round_up(uint64_t length, const pa_sample_spec *spec) {
+ size_t fs;
+ pa_usec_t usec;
+
+ pa_assert(spec);
+
+ fs = pa_frame_size(spec);
+ length = (length + fs - 1) / fs;
+
+ usec = (pa_usec_t) length * PA_USEC_PER_SEC;
+
+ return (usec + spec->rate - 1) / spec->rate;
+}
+
+/* Similar to pa_usec_to_bytes() but rounds up, not down */
+
+size_t pa_usec_to_bytes_round_up(pa_usec_t t, const pa_sample_spec *spec) {
+ uint64_t u;
+ pa_assert(spec);
+
+ u = (uint64_t) t * (uint64_t) spec->rate;
+
+ u = (u + PA_USEC_PER_SEC - 1) / PA_USEC_PER_SEC;
+
+ u *= pa_frame_size(spec);
+
+ return (size_t) u;
+}
diff --git a/src/pulsecore/sample-util.h b/src/pulsecore/sample-util.h
index cef70750..2fe2c81d 100644
--- a/src/pulsecore/sample-util.h
+++ b/src/pulsecore/sample-util.h
@@ -71,11 +71,14 @@ void pa_volume_memchunk(
size_t pa_frame_align(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
-int pa_frame_aligned(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
+pa_bool_t pa_frame_aligned(size_t l, const pa_sample_spec *ss) PA_GCC_PURE;
void pa_interleave(const void *src[], unsigned channels, void *dst, size_t ss, unsigned n);
void pa_deinterleave(const void *src, void *dst[], unsigned channels, size_t ss, unsigned n);
void pa_sample_clamp(pa_sample_format_t format, void *dst, size_t dstr, const void *src, size_t sstr, unsigned n);
+pa_usec_t pa_bytes_to_usec_round_up(uint64_t length, const pa_sample_spec *spec);
+size_t pa_usec_to_bytes_round_up(pa_usec_t t, const pa_sample_spec *spec);
+
#endif
diff --git a/src/pulsecore/sconv-s16le.c b/src/pulsecore/sconv-s16le.c
index 41670f27..159c4655 100644
--- a/src/pulsecore/sconv-s16le.c
+++ b/src/pulsecore/sconv-s16le.c
@@ -70,13 +70,13 @@ void pa_sconv_s16le_to_float32ne(unsigned n, const int16_t *a, float *b) {
for (; n > 0; n--) {
int16_t s = *(a++);
- *(b++) = ((float) INT16_FROM(s))/0x7FFF;
+ *(b++) = ((float) INT16_FROM(s))/(float) 0x7FFF;
}
#else
{
static const double add = 0, factor = 1.0/0x7FFF;
- oil_scaleconv_f32_s16(b, a, n, &add, &factor);
+ oil_scaleconv_f32_s16(b, a, (int) n, &add, &factor);
}
#endif
}
@@ -95,7 +95,7 @@ void pa_sconv_s32le_to_float32ne(unsigned n, const int32_t *a, float *b) {
#else
{
static const double add = 0, factor = 1.0/0x7FFFFFFF;
- oil_scaleconv_f32_s32(b, a, n, &add, &factor);
+ oil_scaleconv_f32_s32(b, a, (int) n, &add, &factor);
}
#endif
}
@@ -110,15 +110,15 @@ void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, int16_t *b) {
int16_t s;
float v = *(a++);
- v = PA_CLAMP_UNLIKELY(v, -1, 1);
- s = (int16_t) (v * 0x7FFF);
+ v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.f);
+ s = (int16_t) lrintf(v * 0x7FFF);
*(b++) = INT16_TO(s);
}
#else
{
static const double add = 0, factor = 0x7FFF;
- oil_scaleconv_s16_f32(b, a, n, &add, &factor);
+ oil_scaleconv_s16_f32(b, a, (int) n, &add, &factor);
}
#endif
}
@@ -133,15 +133,15 @@ void pa_sconv_s32le_from_float32ne(unsigned n, const float *a, int32_t *b) {
int32_t s;
float v = *(a++);
- v = PA_CLAMP_UNLIKELY(v, -1, 1);
- s = (int32_t) ((double) v * (double) 0x7FFFFFFF);
+ v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
+ s = (int32_t) lrint((double) v * (double) 0x7FFFFFFF);
*(b++) = INT32_TO(s);
}
#else
{
static const double add = 0, factor = 0x7FFFFFFF;
- oil_scaleconv_s32_f32(b, a, n, &add, &factor);
+ oil_scaleconv_s32_f32(b, a, (int) n, &add, &factor);
}
#endif
}
@@ -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_CLAMP_UNLIKELY(v, -1, 1);
- s = (int16_t) (v * 0x7FFF);
+ v = PA_FLOAT32_SWAP(v);
+ v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
+ 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_CLAMP_UNLIKELY(v, -1, 1);
- s = (int32_t) ((double) v * 0x7FFFFFFF);
+ v = PA_FLOAT32_SWAP(v);
+ v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
+ s = (int32_t) lrint((double) v * 0x7FFFFFFF);
*(b++) = INT32_TO(s);
}
}
@@ -219,7 +215,7 @@ void pa_sconv_s32le_to_s16re(unsigned n, const int32_t*a, int16_t *b) {
for (; n > 0; n--) {
int16_t s = (int16_t) (INT32_FROM(*a) >> 16);
- *b = PA_UINT32_SWAP(s);
+ *b = PA_INT16_SWAP(s);
a++;
b++;
}
@@ -241,7 +237,7 @@ void pa_sconv_s32le_from_s16re(unsigned n, const int16_t *a, int32_t *b) {
pa_assert(b);
for (; n > 0; n--) {
- int32_t s = ((int32_t) PA_UINT16_SWAP(*a)) << 16;
+ int32_t s = ((int32_t) PA_INT16_SWAP(*a)) << 16;
*b = INT32_TO(s);
a++;
b++;
diff --git a/src/pulsecore/sconv.c b/src/pulsecore/sconv.c
index 581e4681..6c4d420e 100644
--- a/src/pulsecore/sconv.c
+++ b/src/pulsecore/sconv.c
@@ -46,7 +46,7 @@ static void u8_to_float32ne(unsigned n, const uint8_t *a, float *b) {
pa_assert(a);
pa_assert(b);
- oil_scaleconv_f32_u8(b, a, n, &add, &factor);
+ oil_scaleconv_f32_u8(b, a, (int) n, &add, &factor);
}
static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) {
@@ -55,7 +55,7 @@ static void u8_from_float32ne(unsigned n, const float *a, uint8_t *b) {
pa_assert(a);
pa_assert(b);
- oil_scaleconv_u8_f32(b, a, n, &add, &factor);
+ oil_scaleconv_u8_f32(b, a, (int) n, &add, &factor);
}
static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {
@@ -64,9 +64,9 @@ static void u8_to_s16ne(unsigned n, const uint8_t *a, int16_t *b) {
pa_assert(a);
pa_assert(b);
- oil_conv_s16_u8(b, 2, a, 1, n);
- oil_scalaradd_s16(b, 2, b, 2, &add, n);
- oil_scalarmult_s16(b, 2, b, 2, &factor, n);
+ oil_conv_s16_u8(b, 2, a, 1, (int) n);
+ oil_scalaradd_s16(b, 2, b, 2, &add, (int) n);
+ oil_scalarmult_s16(b, 2, b, 2, &factor, (int) n);
}
static void u8_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
@@ -84,7 +84,7 @@ static void float32ne_to_float32ne(unsigned n, const float *a, float *b) {
pa_assert(a);
pa_assert(b);
- oil_memcpy(b, a, sizeof(float) * n);
+ oil_memcpy(b, a, (int) (sizeof(float) * n));
}
static void float32re_to_float32ne(unsigned n, const float *a, float *b) {
@@ -101,7 +101,7 @@ static void s16ne_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {
pa_assert(a);
pa_assert(b);
- oil_memcpy(b, a, sizeof(int16_t) * n);
+ oil_memcpy(b, a, (int) (sizeof(int16_t) * n));
}
static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {
@@ -109,7 +109,7 @@ static void s16re_to_s16ne(unsigned n, const int16_t *a, int16_t *b) {
pa_assert(b);
for (; n > 0; n--, a++, b++)
- *b = PA_UINT16_SWAP(*a);
+ *b = PA_INT16_SWAP(*a);
}
/* ulaw */
@@ -128,9 +128,9 @@ static void ulaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {
for (; n > 0; n--) {
float v = *(a++);
- v = PA_CLAMP_UNLIKELY(v, -1, 1);
+ v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
v *= 0x1FFF;
- *(b++) = st_14linear2ulaw((int16_t) v);
+ *(b++) = st_14linear2ulaw((int16_t) lrintf(v));
}
}
@@ -166,9 +166,9 @@ static void alaw_from_float32ne(unsigned n, const float *a, uint8_t *b) {
for (; n > 0; n--, a++, b++) {
float v = *a;
- v = PA_CLAMP_UNLIKELY(v, -1, 1);
+ v = PA_CLAMP_UNLIKELY(v, -1.0f, 1.0f);
v *= 0xFFF;
- *b = st_13linear2alaw((int16_t) v);
+ *b = st_13linear2alaw((int16_t) lrintf(v));
}
}
@@ -177,7 +177,7 @@ static void alaw_to_s16ne(unsigned n, const int8_t *a, int16_t *b) {
pa_assert(b);
for (; n > 0; n--, a++, b++)
- *b = st_alaw2linear16(*a);
+ *b = st_alaw2linear16((uint8_t) *a);
}
static void alaw_from_s16ne(unsigned n, const int16_t *a, uint8_t *b) {
diff --git a/src/pulsecore/shm.c b/src/pulsecore/shm.c
index 298bf716..c59d247c 100644
--- a/src/pulsecore/shm.c
+++ b/src/pulsecore/shm.c
@@ -73,10 +73,10 @@
struct shm_marker PA_GCC_PACKED {
pa_atomic_t marker; /* 0xbeefcafe */
pa_atomic_t pid;
- uint64_t *_reserverd1;
- uint64_t *_reserverd2;
- uint64_t *_reserverd3;
- uint64_t *_reserverd4;
+ uint64_t _reserved1;
+ uint64_t _reserved2;
+ uint64_t _reserved3;
+ uint64_t _reserved4;
};
static char *segment_name(char *fn, size_t l, unsigned id) {
@@ -105,7 +105,7 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
m->size = size;
#ifdef MAP_ANONYMOUS
- if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0)) == MAP_FAILED) {
+ if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, (off_t) 0)) == MAP_FAILED) {
pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
}
@@ -138,12 +138,12 @@ int pa_shm_create_rw(pa_shm *m, size_t size, pa_bool_t shared, mode_t mode) {
m->size = size + PA_ALIGN(sizeof(struct shm_marker));
- if (ftruncate(fd, m->size) < 0) {
+ if (ftruncate(fd, (off_t) m->size) < 0) {
pa_log("ftruncate() failed: %s", pa_cstrerror(errno));
goto fail;
}
- if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+ if ((m->ptr = mmap(NULL, m->size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
}
@@ -235,7 +235,7 @@ void pa_shm_punch(pa_shm *m, size_t offset, size_t size) {
/* Align this to multiples of the page size */
ptr = (uint8_t*) m->ptr + offset;
- o = (uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr);
+ o = (size_t) ((uint8_t*) ptr - (uint8_t*) PA_PAGE_ALIGN_PTR(ptr));
if (o > 0) {
ps = PA_PAGE_SIZE;
@@ -289,9 +289,9 @@ int pa_shm_attach_ro(pa_shm *m, unsigned id) {
goto fail;
}
- m->size = st.st_size;
+ m->size = (size_t) st.st_size;
- if ((m->ptr = mmap(NULL, m->size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) {
+ if ((m->ptr = mmap(NULL, m->size, PROT_READ, MAP_SHARED, fd, (off_t) 0)) == MAP_FAILED) {
pa_log("mmap() failed: %s", pa_cstrerror(errno));
goto fail;
}
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index 64a6cdf9..0e1224f1 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -75,7 +75,7 @@ void pa_sink_input_new_data_set_volume(pa_sink_input_new_data *data, const pa_cv
pa_assert(data);
if ((data->volume_is_set = !!volume))
- data->volume = *volume;
+ data->volume = data->virtual_volume = *volume;
}
void pa_sink_input_new_data_set_muted(pa_sink_input_new_data *data, pa_bool_t mute) {
@@ -108,6 +108,7 @@ static void reset_callbacks(pa_sink_input *i) {
i->kill = NULL;
i->get_latency = NULL;
i->state_change = NULL;
+ i->may_move_to = NULL;
}
/* Called from main context */
@@ -119,6 +120,7 @@ pa_sink_input* pa_sink_input_new(
pa_sink_input *i;
pa_resampler *resampler = NULL;
char st[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
+ pa_channel_map original_cm;
pa_assert(core);
pa_assert(data);
@@ -141,20 +143,25 @@ pa_sink_input* pa_sink_input_new(
pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec));
if (!data->channel_map_is_set) {
- if (data->sink->channel_map.channels == data->sample_spec.channels)
+ if (pa_channel_map_compatible(&data->sink->channel_map, &data->sample_spec))
data->channel_map = data->sink->channel_map;
else
- pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
+ pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
}
pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
- pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
+ pa_return_null_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec));
- if (!data->volume_is_set)
+ if (!data->volume_is_set) {
pa_cvolume_reset(&data->volume, data->sample_spec.channels);
+ pa_cvolume_reset(&data->virtual_volume, data->sample_spec.channels);
+ }
pa_return_null_if_fail(pa_cvolume_valid(&data->volume));
- pa_return_null_if_fail(data->volume.channels == data->sample_spec.channels);
+ pa_return_null_if_fail(pa_cvolume_compatible(&data->volume, &data->sample_spec));
+
+ pa_return_null_if_fail(pa_cvolume_valid(&data->virtual_volume));
+ pa_return_null_if_fail(pa_cvolume_compatible(&data->virtual_volume, &data->sample_spec));
if (!data->muted_is_set)
data->muted = FALSE;
@@ -165,6 +172,8 @@ pa_sink_input* pa_sink_input_new(
if (flags & PA_SINK_INPUT_FIX_RATE)
data->sample_spec.rate = data->sink->sample_spec.rate;
+ original_cm = data->channel_map;
+
if (flags & PA_SINK_INPUT_FIX_CHANNELS) {
data->sample_spec.channels = data->sink->sample_spec.channels;
data->channel_map = data->sink->channel_map;
@@ -174,8 +183,7 @@ pa_sink_input* pa_sink_input_new(
pa_assert(pa_channel_map_valid(&data->channel_map));
/* Due to the fixing of the sample spec the volume might not match anymore */
- if (data->volume.channels != data->sample_spec.channels)
- pa_cvolume_set(&data->volume, data->sample_spec.channels, pa_cvolume_avg(&data->volume));
+ pa_cvolume_remap(&data->volume, &original_cm, &data->channel_map);
if (data->resample_method == PA_RESAMPLER_INVALID)
data->resample_method = core->resample_method;
@@ -201,7 +209,8 @@ pa_sink_input* pa_sink_input_new(
data->resample_method,
((flags & PA_SINK_INPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
((flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
- (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
+ (core->disable_remixing || (flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
+ (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return NULL;
}
@@ -226,7 +235,9 @@ pa_sink_input* pa_sink_input_new(
i->sample_spec = data->sample_spec;
i->channel_map = data->channel_map;
+ i->virtual_volume = data->virtual_volume;
i->volume = data->volume;
+
i->muted = data->muted;
if (data->sync_base) {
@@ -535,7 +546,7 @@ int pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, pa
* data, so let's just hand out silence */
pa_atomic_store(&i->thread_info.drained, 1);
- pa_memblockq_seek(i->thread_info.render_memblockq, slength, PA_SEEK_RELATIVE);
+ pa_memblockq_seek(i->thread_info.render_memblockq, (int64_t) slength, PA_SEEK_RELATIVE);
i->thread_info.playing_for = 0;
if (i->thread_info.underrun_for != (uint64_t) -1)
i->thread_info.underrun_for += ilength;
@@ -756,14 +767,11 @@ pa_usec_t pa_sink_input_set_requested_latency(pa_sink_input *i, pa_usec_t usec)
if (PA_SINK_INPUT_IS_LINKED(i->state))
pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
- else {
+ else
/* If this sink input is not realized yet, we have to touch
* the thread info data directly */
- usec = fixup_latency(i->sink, usec);
i->thread_info.requested_sink_latency = usec;
- i->sink->thread_info.requested_latency_valid = FALSE;
- }
return usec;
}
@@ -786,17 +794,34 @@ pa_usec_t pa_sink_input_get_requested_latency(pa_sink_input *i) {
/* Called from main context */
void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) {
+ pa_sink_input_set_volume_data data;
+
pa_sink_input_assert_ref(i);
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
pa_assert(volume);
+ pa_assert(pa_cvolume_valid(volume));
+ pa_assert(pa_cvolume_compatible(volume, &i->sample_spec));
+
+ data.sink_input = i;
+ data.virtual_volume = *volume;
+ data.volume = *volume;
+
+ /* If you change something here, consider looking into
+ * module-flat-volume.c as well since it uses very similar
+ * code. */
- if (pa_cvolume_equal(&i->volume, volume))
+ if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_SET_VOLUME], &data) < 0)
return;
- i->volume = *volume;
+ if (!pa_cvolume_equal(&i->volume, &data.volume)) {
+ i->volume = data.volume;
+ pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &data.volume, 0, NULL) == 0);
+ }
- pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i), PA_SINK_INPUT_MESSAGE_SET_VOLUME, &i->volume, 0, NULL) == 0);
- pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+ if (!pa_cvolume_equal(&i->virtual_volume, &data.virtual_volume)) {
+ i->virtual_volume = data.virtual_volume;
+ pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index);
+ }
}
/* Called from main context */
@@ -804,7 +829,7 @@ const pa_cvolume *pa_sink_input_get_volume(pa_sink_input *i) {
pa_sink_input_assert_ref(i);
pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
- return &i->volume;
+ return &i->virtual_volume;
}
/* Called from main context */
@@ -887,6 +912,35 @@ pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) {
}
/* Called from main context */
+pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest) {
+ pa_sink_input_assert_ref(i);
+ pa_assert(PA_SINK_INPUT_IS_LINKED(i->state));
+ pa_sink_assert_ref(dest);
+
+ if (dest == i->sink)
+ return TRUE;
+
+ if (i->flags & PA_SINK_INPUT_DONT_MOVE)
+ return FALSE;
+
+ if (i->sync_next || i->sync_prev) {
+ pa_log_warn("Moving synchronised streams not supported.");
+ return FALSE;
+ }
+
+ if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
+ pa_log_warn("Failed to move sink input: too many inputs per sink.");
+ return FALSE;
+ }
+
+ if (i->may_move_to)
+ if (!i->may_move_to(i, dest))
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Called from main context */
int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
pa_resampler *new_resampler;
pa_sink *origin;
@@ -902,18 +956,8 @@ int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest) {
if (dest == origin)
return 0;
- if (i->flags & PA_SINK_INPUT_DONT_MOVE)
- return -1;
-
- if (i->sync_next || i->sync_prev) {
- pa_log_warn("Moving synchronised streams not supported.");
+ if (!pa_sink_input_may_move_to(i, dest))
return -1;
- }
-
- if (pa_idxset_size(dest->inputs) >= PA_MAX_INPUTS_PER_SINK) {
- pa_log_warn("Failed to move sink input: too many inputs per sink.");
- return -1;
- }
/* Kill directly connected outputs */
while ((o = pa_idxset_first(i->direct_outputs, NULL))) {
@@ -1032,6 +1076,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-input.h b/src/pulsecore/sink-input.h
index c07a7404..27125988 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -56,7 +56,8 @@ typedef enum pa_sink_input_flags {
PA_SINK_INPUT_NO_REMIX = 16,
PA_SINK_INPUT_FIX_FORMAT = 32,
PA_SINK_INPUT_FIX_RATE = 64,
- PA_SINK_INPUT_FIX_CHANNELS = 128
+ PA_SINK_INPUT_FIX_CHANNELS = 128,
+ PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND = 256,
} pa_sink_input_flags_t;
struct pa_sink_input {
@@ -89,6 +90,8 @@ struct pa_sink_input {
pa_sink_input *sync_prev, *sync_next;
+ pa_cvolume virtual_volume;
+
pa_cvolume volume;
pa_bool_t muted;
@@ -154,10 +157,15 @@ struct pa_sink_input {
returns */
pa_usec_t (*get_latency) (pa_sink_input *i); /* may be NULL */
- /* If non_NULL this function is called from thread context if the
+ /* If non-NULL this function is called from thread context if the
* state changes. The old state is found in thread_info.state. */
void (*state_change) (pa_sink_input *i, pa_sink_input_state_t state); /* may be NULL */
+ /* If non-NULL this function is called before this sink input is
+ * move to a sink and if it returns FALSE the move will not
+ * be allowed */
+ pa_bool_t (*may_move_to) (pa_sink_input *i, pa_sink *s); /* may be NULL */
+
struct {
pa_sink_input_state_t state;
pa_atomic_t drained;
@@ -212,19 +220,22 @@ typedef struct pa_sink_input_new_data {
pa_sink *sink;
+ pa_resample_method_t resample_method;
+
+ pa_sink_input *sync_base;
+
pa_sample_spec sample_spec;
- pa_bool_t sample_spec_is_set;
pa_channel_map channel_map;
- pa_bool_t channel_map_is_set;
- pa_cvolume volume;
- pa_bool_t volume_is_set;
- pa_bool_t muted;
- pa_bool_t muted_is_set;
+ pa_cvolume virtual_volume;
- pa_resample_method_t resample_method;
+ pa_cvolume volume;
+ pa_bool_t muted:1;
- pa_sink_input *sync_base;
+ pa_bool_t sample_spec_is_set:1;
+ pa_bool_t channel_map_is_set:1;
+ pa_bool_t volume_is_set:1;
+ pa_bool_t muted_is_set:1;
} pa_sink_input_new_data;
pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
@@ -239,6 +250,12 @@ typedef struct pa_sink_input_move_hook_data {
pa_sink *destination;
} pa_sink_input_move_hook_data;
+typedef struct pa_sink_set_input_volume_data {
+ pa_sink_input *sink_input;
+ pa_cvolume virtual_volume;
+ pa_cvolume volume;
+} pa_sink_input_set_volume_data;
+
/* To be called by the implementing module only */
pa_sink_input* pa_sink_input_new(
@@ -281,6 +298,7 @@ pa_bool_t pa_sink_input_get_mute(pa_sink_input *i);
pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i);
int pa_sink_input_move_to(pa_sink_input *i, pa_sink *dest);
+pa_bool_t pa_sink_input_may_move_to(pa_sink_input *i, pa_sink *dest);
pa_sink_input_state_t pa_sink_input_get_state(pa_sink_input *i);
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 4102f31d..a6027e70 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);
@@ -844,30 +843,55 @@ pa_usec_t pa_sink_get_latency(pa_sink *s) {
/* Called from main thread */
void pa_sink_set_volume(pa_sink *s, const pa_cvolume *volume) {
pa_bool_t changed;
+ pa_sink_set_volume_data data;
pa_sink_assert_ref(s);
pa_assert(PA_SINK_IS_LINKED(s->state));
pa_assert(volume);
+ pa_assert(pa_cvolume_valid(volume));
+ pa_assert(pa_cvolume_compatible(volume, &s->sample_spec));
- changed = !pa_cvolume_equal(volume, &s->volume);
- s->volume = *volume;
+ data.sink = s;
+ data.volume = *volume;
+
+ changed = !pa_cvolume_equal(&data.volume, &s->volume);
+
+ if (changed) {
+ if (pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_SET_VOLUME], &data) < 0)
+ return;
+
+ changed = !pa_cvolume_equal(&data.volume, &s->volume);
+ }
+
+ s->volume = data.volume;
if (s->set_volume && s->set_volume(s) < 0)
s->set_volume = NULL;
if (!s->set_volume)
- pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, volume, 0, NULL);
+ pa_sink_set_soft_volume(s, volume);
if (changed)
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
}
/* Called from main thread */
-const pa_cvolume *pa_sink_get_volume(pa_sink *s) {
+void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume) {
+ pa_sink_assert_ref(s);
+ pa_assert(volume);
+
+ if (PA_SINK_IS_LINKED(s->state))
+ pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_VOLUME, volume, 0, NULL);
+ else
+ s->thread_info.soft_volume = *volume;
+}
+
+/* Called from main thread */
+const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_bool_t force_refresh) {
pa_sink_assert_ref(s);
pa_assert(PA_SINK_IS_LINKED(s->state));
- if (s->refresh_volume) {
+ if (s->refresh_volume || force_refresh) {
struct pa_cvolume old_volume = s->volume;
if (s->get_volume && s->get_volume(s) < 0)
@@ -904,12 +928,12 @@ void pa_sink_set_mute(pa_sink *s, pa_bool_t mute) {
}
/* Called from main thread */
-pa_bool_t pa_sink_get_mute(pa_sink *s) {
+pa_bool_t pa_sink_get_mute(pa_sink *s, pa_bool_t force_refresh) {
pa_sink_assert_ref(s);
pa_assert(PA_SINK_IS_LINKED(s->state));
- if (s->refresh_muted) {
+ if (s->refresh_muted || force_refresh) {
pa_bool_t old_muted = s->muted;
if (s->get_mute && s->get_mute(s) < 0)
@@ -967,7 +991,7 @@ unsigned pa_sink_linked_by(pa_sink *s) {
ret = pa_idxset_size(s->inputs);
/* We add in the number of streams connected to us here. Please
- * not the asymmmetry to pa_sink_used_by()! */
+ * note the asymmmetry to pa_sink_used_by()! */
if (s->monitor_source)
ret += pa_source_linked_by(s->monitor_source);
@@ -991,6 +1015,38 @@ unsigned pa_sink_used_by(pa_sink *s) {
return ret - s->n_corked;
}
+/* Called from main thread */
+unsigned pa_sink_check_suspend(pa_sink *s) {
+ unsigned ret;
+ pa_sink_input *i;
+ uint32_t idx;
+
+ pa_sink_assert_ref(s);
+ pa_assert(PA_SINK_IS_LINKED(s->state));
+
+ ret = 0;
+
+ for (i = PA_SINK_INPUT(pa_idxset_first(s->inputs, &idx)); i; i = PA_SINK_INPUT(pa_idxset_next(s->inputs, &idx))) {
+ pa_sink_input_state_t st;
+
+ st = pa_sink_input_get_state(i);
+ pa_assert(PA_SINK_INPUT_IS_LINKED(st));
+
+ if (st == PA_SINK_INPUT_CORKED)
+ continue;
+
+ if (i->flags & PA_SINK_INPUT_DONT_INHIBIT_AUTO_SUSPEND)
+ continue;
+
+ ret ++;
+ }
+
+ if (s->monitor_source)
+ ret += pa_source_check_suspend(s->monitor_source);
+
+ return ret;
+}
+
/* Called from IO thread, except when it is not */
int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
pa_sink *s = PA_SINK(o);
@@ -1031,11 +1087,15 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
pa_sink_input_set_state_within_thread(i, i->state);
+ /* The requested latency of the sink input needs to be
+ * fixed up and then configured on the sink */
+
+ if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
+ pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
+
pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
pa_sink_input_update_max_request(i, s->thread_info.max_request);
- pa_sink_invalidate_requested_latency(s);
-
/* We don't rewind here automatically. This is left to the
* sink input implementor because some sink inputs need a
* slow start, i.e. need some time to buffer client
@@ -1147,11 +1207,12 @@ int pa_sink_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offse
if (i->attach)
i->attach(i);
+ if (i->thread_info.requested_sink_latency != (pa_usec_t) -1)
+ pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
+
pa_sink_input_update_max_rewind(i, s->thread_info.max_rewind);
pa_sink_input_update_max_request(i, s->thread_info.max_request);
- pa_sink_input_set_requested_latency_within_thread(i, i->thread_info.requested_sink_latency);
-
if (i->thread_info.state != PA_SINK_INPUT_CORKED) {
pa_usec_t usec = 0;
size_t nbytes;
@@ -1413,7 +1474,6 @@ void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind) {
/* Called from IO thread */
void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
- pa_sink_input *i;
void *state = NULL;
pa_sink_assert_ref(s);
@@ -1424,6 +1484,8 @@ void pa_sink_set_max_request(pa_sink *s, size_t max_request) {
s->thread_info.max_request = max_request;
if (PA_SINK_IS_LINKED(s->thread_info.state)) {
+ pa_sink_input *i;
+
while ((i = pa_hashmap_iterate(s->thread_info.inputs, &state, NULL)))
pa_sink_input_update_max_request(i, s->thread_info.max_request);
}
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 604be269..c5a73214 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -180,21 +180,22 @@ typedef enum pa_sink_message {
typedef struct pa_sink_new_data {
char *name;
- pa_bool_t namereg_fail;
pa_proplist *proplist;
const char *driver;
pa_module *module;
pa_sample_spec sample_spec;
- pa_bool_t sample_spec_is_set;
pa_channel_map channel_map;
- pa_bool_t channel_map_is_set;
-
pa_cvolume volume;
- pa_bool_t volume_is_set;
- pa_bool_t muted;
- pa_bool_t muted_is_set;
+ pa_bool_t muted :1;
+
+ pa_bool_t sample_spec_is_set:1;
+ pa_bool_t channel_map_is_set:1;
+ pa_bool_t volume_is_set:1;
+ pa_bool_t muted_is_set:1;
+
+ pa_bool_t namereg_fail:1;
} pa_sink_new_data;
pa_sink_new_data* pa_sink_new_data_init(pa_sink_new_data *data);
@@ -205,6 +206,11 @@ void pa_sink_new_data_set_volume(pa_sink_new_data *data, const pa_cvolume *volum
void pa_sink_new_data_set_muted(pa_sink_new_data *data, pa_bool_t mute);
void pa_sink_new_data_done(pa_sink_new_data *data);
+typedef struct pa_sink_set_volume_data {
+ pa_sink *sink;
+ pa_cvolume volume;
+} pa_sink_set_volume_data;
+
/* To be called exclusively by the sink driver, from main context */
pa_sink* pa_sink_new(
@@ -239,12 +245,14 @@ int pa_sink_suspend(pa_sink *s, pa_bool_t suspend);
int pa_sink_suspend_all(pa_core *c, pa_bool_t suspend);
void pa_sink_set_volume(pa_sink *sink, const pa_cvolume *volume);
-const pa_cvolume *pa_sink_get_volume(pa_sink *sink);
+void pa_sink_set_soft_volume(pa_sink *s, const pa_cvolume *volume);
+const pa_cvolume *pa_sink_get_volume(pa_sink *sink, pa_bool_t force_refresh);
void pa_sink_set_mute(pa_sink *sink, pa_bool_t mute);
-pa_bool_t pa_sink_get_mute(pa_sink *sink);
+pa_bool_t pa_sink_get_mute(pa_sink *sink, pa_bool_t force_refres);
unsigned pa_sink_linked_by(pa_sink *s); /* Number of connected streams */
unsigned pa_sink_used_by(pa_sink *s); /* Number of connected streams which are not corked */
+unsigned pa_sink_check_suspend(pa_sink *s); /* Returns how many streams are active that don't allow suspensions */
#define pa_sink_get_state(s) ((s)->state)
/* To be called exclusively by the sink driver, from IO context */
diff --git a/src/pulsecore/socket-client.c b/src/pulsecore/socket-client.c
index e69a63da..6739effd 100644
--- a/src/pulsecore/socket-client.c
+++ b/src/pulsecore/socket-client.c
@@ -187,7 +187,7 @@ static void connect_defer_cb(pa_mainloop_api *m, pa_defer_event *e, void *userda
do_call(c);
}
-static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) {
+static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
pa_socket_client *c = userdata;
pa_assert(m);
@@ -283,7 +283,7 @@ static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size
else
pa_make_socket_low_delay(c->fd);
- if (do_connect(c, sa, salen) < 0)
+ if (do_connect(c, sa, (socklen_t) salen) < 0)
return -1;
return 0;
@@ -370,7 +370,7 @@ pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[
#ifdef HAVE_LIBASYNCNS
-static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) {
+static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
pa_socket_client *c = userdata;
struct addrinfo *res = NULL;
int ret;
@@ -437,7 +437,7 @@ static void start_timeout(pa_socket_client *c) {
pa_assert(!c->timeout_event);
pa_gettimeofday(&tv);
- pa_timeval_add(&tv, CONNECT_TIMEOUT * 1000000);
+ pa_timeval_add(&tv, CONNECT_TIMEOUT * PA_USEC_PER_SEC);
c->timeout_event = c->mainloop->time_new(c->mainloop, &tv, timeout_cb, c);
}
diff --git a/src/pulsecore/socket-server.c b/src/pulsecore/socket-server.c
index 9885a02b..a600e0a6 100644
--- a/src/pulsecore/socket-server.c
+++ b/src/pulsecore/socket-server.c
@@ -199,7 +199,7 @@ pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *file
pa_make_socket_low_delay(fd);
- if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) {
+ if (bind(fd, (struct sockaddr*) &sa, (socklen_t) SUN_LEN(&sa)) < 0) {
pa_log("bind(): %s", pa_cstrerror(errno));
goto fail;
}
diff --git a/src/pulsecore/sound-file-stream.c b/src/pulsecore/sound-file-stream.c
index 8b2a29b9..c30c16eb 100644
--- a/src/pulsecore/sound-file-stream.c
+++ b/src/pulsecore/sound-file-stream.c
@@ -170,10 +170,10 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
if (u->readf_function) {
fs = pa_frame_size(&i->sample_spec);
- n = u->readf_function(u->sndfile, p, length/fs);
+ n = u->readf_function(u->sndfile, p, (sf_count_t) (length/fs));
} else {
fs = 1;
- n = sf_read_raw(u->sndfile, p, length);
+ n = sf_read_raw(u->sndfile, p, (sf_count_t) length);
}
pa_memblock_release(tchunk.memblock);
@@ -186,7 +186,7 @@ static int sink_input_pop_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk
break;
}
- tchunk.length = n * fs;
+ tchunk.length = (size_t) n * fs;
pa_memblockq_push(u->memblockq, &tchunk);
pa_memblock_unref(tchunk.memblock);
@@ -310,8 +310,8 @@ int pa_play_file(
break;
}
- ss.rate = sfinfo.samplerate;
- ss.channels = sfinfo.channels;
+ ss.rate = (uint32_t) sfinfo.samplerate;
+ ss.channels = (uint8_t) sfinfo.channels;
if (!pa_sample_spec_valid(&ss)) {
pa_log("Unsupported sample format in file %s", fname);
diff --git a/src/pulsecore/sound-file.c b/src/pulsecore/sound-file.c
index 3183ede6..380cef16 100644
--- a/src/pulsecore/sound-file.c
+++ b/src/pulsecore/sound-file.c
@@ -89,7 +89,7 @@ int pa_sound_file_load(
case SF_FORMAT_PCM_U8:
case SF_FORMAT_PCM_S8:
ss->format = PA_SAMPLE_S16NE;
- readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short;
+ readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *_ptr, sf_count_t frames)) sf_readf_short;
break;
case SF_FORMAT_ULAW:
@@ -104,12 +104,12 @@ int pa_sound_file_load(
case SF_FORMAT_DOUBLE:
default:
ss->format = PA_SAMPLE_FLOAT32NE;
- readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float;
+ readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *_ptr, sf_count_t frames)) sf_readf_float;
break;
}
- ss->rate = sfinfo.samplerate;
- ss->channels = sfinfo.channels;
+ ss->rate = (uint32_t) sfinfo.samplerate;
+ ss->channels = (uint8_t) sfinfo.channels;
if (!pa_sample_spec_valid(ss)) {
pa_log("Unsupported sample format in file %s", fname);
@@ -119,7 +119,7 @@ int pa_sound_file_load(
if (map)
pa_channel_map_init_extend(map, ss->channels, PA_CHANNEL_MAP_DEFAULT);
- if ((l = pa_frame_size(ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
+ if ((l = pa_frame_size(ss) * (size_t) sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
pa_log("File too large");
goto finish;
}
@@ -131,7 +131,7 @@ int pa_sound_file_load(
ptr = pa_memblock_acquire(chunk->memblock);
if ((readf_function && readf_function(sf, ptr, sfinfo.frames) != sfinfo.frames) ||
- (!readf_function && sf_read_raw(sf, ptr, l) != (sf_count_t) l)) {
+ (!readf_function && sf_read_raw(sf, ptr, (sf_count_t) l) != (sf_count_t) l)) {
pa_log("Premature file end");
goto finish;
}
@@ -189,15 +189,15 @@ int pa_sound_file_too_big_to_cache(const char *fname) {
break;
}
- ss.rate = sfinfo.samplerate;
- ss.channels = sfinfo.channels;
+ ss.rate = (uint32_t) sfinfo.samplerate;
+ ss.channels = (uint8_t) sfinfo.channels;
if (!pa_sample_spec_valid(&ss)) {
pa_log("Unsupported sample format in file %s", fname);
return -1;
}
- if ((pa_frame_size(&ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
+ if ((pa_frame_size(&ss) * (size_t) sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) {
pa_log("File too large: %s", fname);
return 1;
}
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index dbf3af94..376402fa 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -90,6 +90,7 @@ static void reset_callbacks(pa_source_output *o) {
o->kill = NULL;
o->get_latency = NULL;
o->state_change = NULL;
+ o->may_move_to = NULL;
}
/* Called from main context */
@@ -124,14 +125,14 @@ pa_source_output* pa_source_output_new(
pa_return_null_if_fail(pa_sample_spec_valid(&data->sample_spec));
if (!data->channel_map_is_set) {
- if (data->source->channel_map.channels == data->sample_spec.channels)
+ if (pa_channel_map_compatible(&data->source->channel_map, &data->sample_spec))
data->channel_map = data->source->channel_map;
else
- pa_return_null_if_fail(pa_channel_map_init_auto(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT));
+ pa_channel_map_init_extend(&data->channel_map, data->sample_spec.channels, PA_CHANNEL_MAP_DEFAULT);
}
pa_return_null_if_fail(pa_channel_map_valid(&data->channel_map));
- pa_return_null_if_fail(data->channel_map.channels == data->sample_spec.channels);
+ pa_return_null_if_fail(pa_channel_map_compatible(&data->channel_map, &data->sample_spec));
if (flags & PA_SOURCE_OUTPUT_FIX_FORMAT)
data->sample_spec.format = data->source->sample_spec.format;
@@ -171,7 +172,8 @@ pa_source_output* pa_source_output_new(
data->resample_method,
((flags & PA_SOURCE_OUTPUT_VARIABLE_RATE) ? PA_RESAMPLER_VARIABLE_RATE : 0) |
((flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
- (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0)))) {
+ (core->disable_remixing || (flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
+ (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return NULL;
}
@@ -397,7 +399,7 @@ void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) {
if (pa_memblockq_push(o->thread_info.delay_memblockq, chunk) < 0) {
pa_log_debug("Delay queue overflow!");
- pa_memblockq_seek(o->thread_info.delay_memblockq, chunk->length, PA_SEEK_RELATIVE);
+ pa_memblockq_seek(o->thread_info.delay_memblockq, (int64_t) chunk->length, PA_SEEK_RELATIVE);
}
limit = o->process_rewind ? 0 : o->source->thread_info.max_rewind;
@@ -511,14 +513,11 @@ pa_usec_t pa_source_output_set_requested_latency(pa_source_output *o, pa_usec_t
if (PA_SOURCE_OUTPUT_IS_LINKED(o->state))
pa_assert_se(pa_asyncmsgq_send(o->source->asyncmsgq, PA_MSGOBJECT(o), PA_SOURCE_OUTPUT_MESSAGE_SET_REQUESTED_LATENCY, &usec, 0, NULL) == 0);
- else {
+ else
/* If this source output is not realized yet, we have to touch
* the thread info data directly */
- usec = fixup_latency(o->source, usec);
o->thread_info.requested_source_latency = usec;
- o->source->thread_info.requested_latency_valid = FALSE;
- }
return usec;
}
@@ -595,6 +594,32 @@ pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) {
return o->resample_method;
}
+pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest) {
+ pa_source_output_assert_ref(o);
+ pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(o->state));
+ pa_source_assert_ref(dest);
+
+ if (dest == o->source)
+ return TRUE;
+
+ if (o->flags & PA_SOURCE_OUTPUT_DONT_MOVE)
+ return FALSE;
+
+ if (o->direct_on_input)
+ return FALSE;
+
+ if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
+ pa_log_warn("Failed to move source output: too many outputs per source.");
+ return FALSE;
+ }
+
+ if (o->may_move_to)
+ if (!o->may_move_to(o, dest))
+ return FALSE;
+
+ return TRUE;
+}
+
/* Called from main context */
int pa_source_output_move_to(pa_source_output *o, pa_source *dest) {
pa_source *origin;
@@ -610,17 +635,9 @@ int pa_source_output_move_to(pa_source_output *o, pa_source *dest) {
if (dest == origin)
return 0;
- if (o->flags & PA_SOURCE_OUTPUT_DONT_MOVE)
+ if (!pa_source_output_may_move_to(o, dest))
return -1;
- if (o->direct_on_input)
- return -1;
-
- if (pa_idxset_size(dest->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) {
- pa_log_warn("Failed to move source output: too many outputs per source.");
- return -1;
- }
-
if (o->thread_info.resampler &&
pa_sample_spec_equal(&origin->sample_spec, &dest->sample_spec) &&
pa_channel_map_equal(&origin->channel_map, &dest->channel_map))
diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h
index 61825b22..f011f9bd 100644
--- a/src/pulsecore/source-output.h
+++ b/src/pulsecore/source-output.h
@@ -52,7 +52,8 @@ typedef enum pa_source_output_flags {
PA_SOURCE_OUTPUT_NO_REMIX = 16,
PA_SOURCE_OUTPUT_FIX_FORMAT = 32,
PA_SOURCE_OUTPUT_FIX_RATE = 64,
- PA_SOURCE_OUTPUT_FIX_CHANNELS = 128
+ PA_SOURCE_OUTPUT_FIX_CHANNELS = 128,
+ PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND = 256
} pa_source_output_flags_t;
struct pa_source_output {
@@ -126,10 +127,15 @@ struct pa_source_output {
returns */
pa_usec_t (*get_latency) (pa_source_output *o); /* may be NULL */
- /* If non_NULL this function is called from thread context if the
+ /* If non-NULL this function is called from thread context if the
* state changes. The old state is found in thread_info.state. */
void (*state_change) (pa_source_output *o, pa_source_output_state_t state); /* may be NULL */
+ /* If non-NULL this function is called before this source output
+ * is moved to a source and if it returns FALSE the move
+ * will not be allowed */
+ pa_bool_t (*may_move_to) (pa_source_output *o, pa_source *s); /* may be NULL */
+
struct {
pa_source_output_state_t state;
@@ -174,12 +180,13 @@ typedef struct pa_source_output_new_data {
pa_source *source;
+ pa_resample_method_t resample_method;
+
pa_sample_spec sample_spec;
- pa_bool_t sample_spec_is_set;
pa_channel_map channel_map;
- pa_bool_t channel_map_is_set;
- pa_resample_method_t resample_method;
+ pa_bool_t sample_spec_is_set:1;
+ pa_bool_t channel_map_is_set:1;
} pa_source_output_new_data;
pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
@@ -219,6 +226,7 @@ pa_usec_t pa_source_output_get_latency(pa_source_output *i, pa_usec_t *source_la
pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o);
+pa_bool_t pa_source_output_may_move_to(pa_source_output *o, pa_source *dest);
int pa_source_output_move_to(pa_source_output *o, pa_source *dest);
#define pa_source_output_get_state(o) ((o)->state)
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 31620690..7d927faa 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -520,18 +520,29 @@ void pa_source_set_volume(pa_source *s, const pa_cvolume *volume) {
s->set_volume = NULL;
if (!s->set_volume)
- pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, volume, 0, NULL);
+ pa_source_set_soft_volume(s, volume);
if (changed)
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
}
/* Called from main thread */
-const pa_cvolume *pa_source_get_volume(pa_source *s) {
+void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume) {
+ pa_source_assert_ref(s);
+ pa_assert(volume);
+
+ if (PA_SOURCE_IS_LINKED(s->state))
+ pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_VOLUME, volume, 0, NULL);
+ else
+ s->thread_info.soft_volume = *volume;
+}
+
+/* Called from main thread */
+const pa_cvolume *pa_source_get_volume(pa_source *s, pa_bool_t force_refresh) {
pa_source_assert_ref(s);
pa_assert(PA_SOURCE_IS_LINKED(s->state));
- if (s->refresh_volume) {
+ if (s->refresh_volume || force_refresh) {
pa_cvolume old_volume = s->volume;
if (s->get_volume && s->get_volume(s) < 0)
@@ -568,12 +579,12 @@ void pa_source_set_mute(pa_source *s, pa_bool_t mute) {
}
/* Called from main thread */
-pa_bool_t pa_source_get_mute(pa_source *s) {
+pa_bool_t pa_source_get_mute(pa_source *s, pa_bool_t force_refresh) {
pa_source_assert_ref(s);
pa_assert(PA_SOURCE_IS_LINKED(s->state));
- if (s->refresh_muted) {
+ if (s->refresh_muted || force_refresh) {
pa_bool_t old_muted = s->muted;
if (s->get_mute && s->get_mute(s) < 0)
@@ -634,6 +645,35 @@ unsigned pa_source_used_by(pa_source *s) {
return ret - s->n_corked;
}
+/* Called from main thread */
+unsigned pa_source_check_suspend(pa_source *s) {
+ unsigned ret;
+ pa_source_output *o;
+ uint32_t idx;
+
+ pa_source_assert_ref(s);
+ pa_assert(PA_SOURCE_IS_LINKED(s->state));
+
+ ret = 0;
+
+ for (o = PA_SOURCE_OUTPUT(pa_idxset_first(s->outputs, &idx)); o; o = PA_SOURCE_OUTPUT(pa_idxset_next(s->outputs, &idx))) {
+ pa_source_output_state_t st;
+
+ st = pa_source_output_get_state(o);
+ pa_assert(PA_SOURCE_OUTPUT_IS_LINKED(st));
+
+ if (st == PA_SOURCE_OUTPUT_CORKED)
+ continue;
+
+ if (o->flags & PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND)
+ continue;
+
+ ret ++;
+ }
+
+ return ret;
+}
+
/* Called from IO thread, except when it is not */
int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
pa_source *s = PA_SOURCE(object);
@@ -659,6 +699,9 @@ int pa_source_process_msg(pa_msgobject *object, int code, void *userdata, int64_
pa_source_output_set_state_within_thread(o, o->state);
+ if (o->thread_info.requested_source_latency != (pa_usec_t) -1)
+ pa_source_output_set_requested_latency_within_thread(o, o->thread_info.requested_source_latency);
+
pa_source_output_update_max_rewind(o, s->thread_info.max_rewind);
/* We don't just invalidate the requested latency here,
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index f4a17e8d..aaf904b4 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -168,21 +168,22 @@ typedef enum pa_source_message {
typedef struct pa_source_new_data {
char *name;
- pa_bool_t namereg_fail;
pa_proplist *proplist;
const char *driver;
pa_module *module;
pa_sample_spec sample_spec;
- pa_bool_t sample_spec_is_set;
pa_channel_map channel_map;
- pa_bool_t channel_map_is_set;
-
pa_cvolume volume;
- pa_bool_t volume_is_set;
- pa_bool_t muted;
- pa_bool_t muted_is_set;
+ pa_bool_t muted:1;
+
+ pa_bool_t volume_is_set:1;
+ pa_bool_t muted_is_set:1;
+ pa_bool_t sample_spec_is_set:1;
+ pa_bool_t channel_map_is_set:1;
+
+ pa_bool_t namereg_fail:1;
} pa_source_new_data;
pa_source_new_data* pa_source_new_data_init(pa_source_new_data *data);
@@ -226,12 +227,14 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend);
int pa_source_suspend_all(pa_core *c, pa_bool_t suspend);
void pa_source_set_volume(pa_source *source, const pa_cvolume *volume);
-const pa_cvolume *pa_source_get_volume(pa_source *source);
+void pa_source_set_soft_volume(pa_source *s, const pa_cvolume *volume);
+const pa_cvolume *pa_source_get_volume(pa_source *source, pa_bool_t force_refresh);
void pa_source_set_mute(pa_source *source, pa_bool_t mute);
-pa_bool_t pa_source_get_mute(pa_source *source);
+pa_bool_t pa_source_get_mute(pa_source *source, pa_bool_t force_refresh);
unsigned pa_source_linked_by(pa_source *s); /* Number of connected streams */
unsigned pa_source_used_by(pa_source *s); /* Number of connected streams that are not corked */
+unsigned pa_source_check_suspend(pa_source *s); /* Returns how many streams are active that don't allow suspensions */
#define pa_source_get_state(s) ((pa_source_state_t) (s)->state)
/* To be called exclusively by the source driver, from IO context */
diff --git a/src/pulsecore/start-child.c b/src/pulsecore/start-child.c
index 1661383d..7774bde6 100644
--- a/src/pulsecore/start-child.c
+++ b/src/pulsecore/start-child.c
@@ -66,11 +66,6 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {
return pipe_fds[0];
} else {
-#ifdef __linux__
- DIR* d;
-#endif
- int max_fd, i;
-
/* child */
pa_reset_priority();
@@ -87,48 +82,9 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {
pa_close(2);
pa_assert_se(open("/dev/null", O_WRONLY) == 2);
-#ifdef __linux__
-
- if ((d = opendir("/proc/self/fd/"))) {
-
- struct dirent *de;
-
- while ((de = readdir(d))) {
- char *e = NULL;
- int fd;
-
- if (de->d_name[0] == '.')
- continue;
-
- errno = 0;
- fd = strtol(de->d_name, &e, 10);
- pa_assert(errno == 0 && e && *e == 0);
-
- if (fd >= 3 && dirfd(d) != fd)
- pa_close(fd);
- }
-
- closedir(d);
- } else {
-
-#endif
-
- max_fd = 1024;
-
-#ifdef HAVE_SYS_RESOURCE_H
- {
- struct rlimit r;
- if (getrlimit(RLIMIT_NOFILE, &r) == 0)
- max_fd = r.rlim_max;
- }
-#endif
-
- for (i = 3; i < max_fd; i++)
- pa_close(i);
-
-#ifdef __linux__
- }
-#endif
+ pa_close_all(-1);
+ pa_reset_sigs(-1);
+ pa_unblock_sigs(-1);
#ifdef PR_SET_PDEATHSIG
/* On Linux we can use PR_SET_PDEATHSIG to have the helper
@@ -139,16 +95,6 @@ int pa_start_child_for_read(const char *name, const char *argv1, pid_t *pid) {
prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
#endif
-#ifdef SIGPIPE
- /* Make sure that SIGPIPE kills the child process */
- signal(SIGPIPE, SIG_DFL);
-#endif
-
-#ifdef SIGTERM
- /* Make sure that SIGTERM kills the child process */
- signal(SIGTERM, SIG_DFL);
-#endif
-
execl(name, name, argv1, NULL);
_exit(1);
}
diff --git a/src/pulsecore/strbuf.c b/src/pulsecore/strbuf.c
index b59b6f49..540faef9 100644
--- a/src/pulsecore/strbuf.c
+++ b/src/pulsecore/strbuf.c
@@ -77,7 +77,7 @@ char *pa_strbuf_tostring(pa_strbuf *sb) {
pa_assert(sb);
- e = t = pa_xnew(char, sb->length+1);
+ e = t = pa_xmalloc(sb->length+1);
for (c = sb->head; c; c = c->next) {
pa_assert((size_t) (e-t) <= sb->length);
@@ -150,8 +150,8 @@ void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) {
/* Append a printf() style formatted string to the string buffer. */
/* The following is based on an example from the GNU libc documentation */
-int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {
- int size = 100;
+size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {
+ size_t size = 100;
struct chunk *c = NULL;
pa_assert(sb);
@@ -168,14 +168,14 @@ int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) {
CHUNK_TO_TEXT(c)[size-1] = 0;
va_end(ap);
- if (r > -1 && r < size) {
- c->length = r;
+ if (r > -1 && (size_t) r < size) {
+ c->length = (size_t) r;
append(sb, c);
- return r;
+ return (size_t) r;
}
if (r > -1) /* glibc 2.1 */
- size = r+1;
+ size = (size_t) r+1;
else /* glibc 2.0 */
size *= 2;
}
diff --git a/src/pulsecore/strbuf.h b/src/pulsecore/strbuf.h
index 24c876d5..ac68d7be 100644
--- a/src/pulsecore/strbuf.h
+++ b/src/pulsecore/strbuf.h
@@ -31,7 +31,7 @@ void pa_strbuf_free(pa_strbuf *sb);
char *pa_strbuf_tostring(pa_strbuf *sb);
char *pa_strbuf_tostring_free(pa_strbuf *sb);
-int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3);
+size_t pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3);
void pa_strbuf_puts(pa_strbuf *sb, const char *t);
void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t m);
diff --git a/src/pulsecore/tagstruct.c b/src/pulsecore/tagstruct.c
index b0ed59ef..62a30144 100644
--- a/src/pulsecore/tagstruct.c
+++ b/src/pulsecore/tagstruct.c
@@ -154,7 +154,7 @@ void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) {
extend(t, 5+length);
t->data[t->length] = PA_TAG_ARBITRARY;
- tmp = htonl(length);
+ tmp = htonl((uint32_t) length);
memcpy(t->data+t->length+1, &tmp, 4);
if (length)
memcpy(t->data+t->length+5, p, length);
@@ -165,7 +165,7 @@ void pa_tagstruct_put_boolean(pa_tagstruct*t, pa_bool_t b) {
pa_assert(t);
extend(t, 1);
- t->data[t->length] = b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE;
+ t->data[t->length] = (uint8_t) (b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE);
t->length += 1;
}
@@ -175,9 +175,9 @@ void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) {
extend(t, 9);
t->data[t->length] = PA_TAG_TIMEVAL;
- tmp = htonl(tv->tv_sec);
+ tmp = htonl((uint32_t) tv->tv_sec);
memcpy(t->data+t->length+1, &tmp, 4);
- tmp = htonl(tv->tv_usec);
+ tmp = htonl((uint32_t) tv->tv_usec);
memcpy(t->data+t->length+5, &tmp, 4);
t->length += 9;
}
@@ -228,7 +228,7 @@ void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) {
unsigned i;
pa_assert(t);
- extend(t, 2 + map->channels);
+ extend(t, 2 + (size_t) map->channels);
t->data[t->length++] = PA_TAG_CHANNEL_MAP;
t->data[t->length++] = map->channels;
@@ -435,9 +435,9 @@ int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) {
return -1;
memcpy(&tv->tv_sec, t->data+t->rindex+1, 4);
- tv->tv_sec = ntohl(tv->tv_sec);
+ tv->tv_sec = (time_t) ntohl((uint32_t) tv->tv_sec);
memcpy(&tv->tv_usec, t->data+t->rindex+5, 4);
- tv->tv_usec = ntohl(tv->tv_usec);
+ tv->tv_usec = (suseconds_t) ntohl((uint32_t) tv->tv_usec);
t->rindex += 9;
return 0;
}
@@ -523,7 +523,7 @@ int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map) {
for (i = 0; i < map->channels; i ++)
map->map[i] = (int8_t) t->data[t->rindex + 2 + i];
- t->rindex += 2 + map->channels;
+ t->rindex += 2 + (size_t) map->channels;
return 0;
}
diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c
index 20ed16d9..ade398f9 100644
--- a/src/pulsecore/thread-posix.c
+++ b/src/pulsecore/thread-posix.c
@@ -41,6 +41,7 @@ struct pa_thread {
pa_thread_func_t thread_func;
void *userdata;
pa_atomic_t running;
+ pa_bool_t joined;
};
struct pa_tls {
@@ -82,6 +83,7 @@ pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {
t = pa_xnew(pa_thread, 1);
t->thread_func = thread_func;
t->userdata = userdata;
+ t->joined = FALSE;
pa_atomic_store(&t->running, 0);
if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) {
@@ -115,7 +117,12 @@ void pa_thread_free(pa_thread *t) {
int pa_thread_join(pa_thread *t) {
pa_assert(t);
+ pa_assert(t->thread_func);
+
+ if (t->joined)
+ return -1;
+ t->joined = TRUE;
return pthread_join(t->id, NULL);
}
@@ -132,6 +139,7 @@ pa_thread* pa_thread_self(void) {
t->id = pthread_self();
t->thread_func = NULL;
t->userdata = NULL;
+ t->joined = TRUE;
pa_atomic_store(&t->running, 2);
PA_STATIC_TLS_SET(current_thread, t);
@@ -192,4 +200,3 @@ void *pa_tls_set(pa_tls *t, void *userdata) {
pa_assert_se(pthread_setspecific(t->key, userdata) == 0);
return r;
}
-
diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h
index f3aca13e..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) { \
@@ -86,7 +89,7 @@ void *pa_tls_set(pa_tls *t, void *userdata);
} \
struct __stupid_useless_struct_to_allow_trailing_semicolon
-#ifdef HAVE_TLS_BUILTIN
+#ifdef SUPPORT_TLS___THREAD
/* An optimized version of the above that requires no dynamic
* allocation if the compiler supports __thread */
#define PA_STATIC_TLS_DECLARE_NO_FREE(name) \
diff --git a/src/pulsecore/time-smoother.c b/src/pulsecore/time-smoother.c
index d0231486..65621948 100644
--- a/src/pulsecore/time-smoother.c
+++ b/src/pulsecore/time-smoother.c
@@ -209,8 +209,8 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
i = s->history_idx;
for (j = s->n_history; j > 0; j--) {
- ax += s->history_x[i];
- ay += s->history_y[i];
+ ax += (int64_t) s->history_x[i];
+ ay += (int64_t) s->history_y[i];
c++;
REDUCE_INC(i);
@@ -236,7 +236,7 @@ static double avg_gradient(pa_smoother *s, pa_usec_t x) {
REDUCE_INC(i);
}
- r = (double) k / t;
+ r = (double) k / (double) t;
return (s->monotonic && r < 0) ? 0 : r;
}
@@ -268,8 +268,8 @@ static void calc_abc(pa_smoother *s) {
/* Calculate a, b, c for y=ax^3+bx^2+cx */
s->c = de;
- s->b = (((double) (3*ky)/kx - dp - 2*de)) / kx;
- s->a = (dp/kx - 2*s->b - de/kx) / (3*kx);
+ s->b = (((double) (3*ky)/ (double) kx - dp - (double) (2*de))) / (double) kx;
+ s->a = (dp/(double) kx - 2*s->b - de/(double) kx) / (double) (3*kx);
s->abc_valid = TRUE;
}
@@ -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 * (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) llrint(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 + s->dp *s->adjust_time;
+ s->py = s->ry + (pa_usec_t) llrint(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) llrint((double) y_delay / nde);
}
void pa_smoother_reset(pa_smoother *s) {
diff --git a/src/pulsecore/tokenizer.c b/src/pulsecore/tokenizer.c
index d1e0836b..07a9f3ac 100644
--- a/src/pulsecore/tokenizer.c
+++ b/src/pulsecore/tokenizer.c
@@ -34,7 +34,7 @@
#include "tokenizer.h"
-static void token_free(void *p, PA_GCC_UNUSED void *userdata) {
+static void token_free(void *p, void *userdata) {
pa_xfree(p);
}
diff --git a/src/pulsecore/x11prop.c b/src/pulsecore/x11prop.c
index 9e75f63a..7f91ba3c 100644
--- a/src/pulsecore/x11prop.c
+++ b/src/pulsecore/x11prop.c
@@ -32,7 +32,7 @@
void pa_x11_set_prop(Display *d, const char *name, const char *data) {
Atom a = XInternAtom(d, name, False);
- XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, strlen(data)+1);
+ XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1));
}
void pa_x11_del_prop(Display *d, const char *name) {
@@ -49,7 +49,7 @@ char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {
char *ret = NULL;
Atom a = XInternAtom(d, name, False);
- if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (l+2)/4, False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success)
+ if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success)
goto finish;
if (actual_type != XA_STRING)
diff --git a/src/pulsecore/x11wrap.c b/src/pulsecore/x11wrap.c
index 17f8e6a4..332ebb2e 100644
--- a/src/pulsecore/x11wrap.c
+++ b/src/pulsecore/x11wrap.c
@@ -91,7 +91,7 @@ static void work(pa_x11_wrapper *w) {
}
/* IO notification event for the X11 display connection */
-static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) {
+static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
pa_x11_wrapper *w = userdata;
pa_assert(m);
@@ -118,7 +118,7 @@ static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) {
}
/* IO notification event for X11 internal connections */
-static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) {
+static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) {
pa_x11_wrapper *w = userdata;
pa_assert(m);
diff --git a/src/tests/channelmap-test.c b/src/tests/channelmap-test.c
index 9c234602..6cf58fb0 100644
--- a/src/tests/channelmap-test.c
+++ b/src/tests/channelmap-test.c
@@ -1,10 +1,14 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdio.h>
#include <assert.h>
#include <pulse/channelmap.h>
#include <pulse/gccmacro.h>
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+int main(int argc, char *argv[]) {
char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
pa_channel_map map, map2;
diff --git a/src/tests/cpulimit-test.c b/src/tests/cpulimit-test.c
index b7145e8a..fdc0162e 100644
--- a/src/tests/cpulimit-test.c
+++ b/src/tests/cpulimit-test.c
@@ -42,7 +42,7 @@ static time_t start;
#ifdef TEST2
-static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UNUSED int sig, PA_GCC_UNUSED void *userdata) {
+static void func(pa_mainloop_api *m, pa_signal_event *e, int sig, void *userdata) {
time_t now;
time(&now);
@@ -55,7 +55,7 @@ static void func(pa_mainloop_api *m, PA_GCC_UNUSED pa_signal_event *e, PA_GCC_UN
#endif
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+int main(int argc, char *argv[]) {
pa_mainloop *m;
m = pa_mainloop_new();
diff --git a/src/tests/envelope-test.c b/src/tests/envelope-test.c
index 9f914553..4a72f5a3 100644
--- a/src/tests/envelope-test.c
+++ b/src/tests/envelope-test.c
@@ -40,7 +40,7 @@ const pa_envelope_def ramp_down = {
.n_points = 2,
.points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
.points_y = {
- .f = { 1.0, 0.2 },
+ .f = { 1.0f, 0.2f },
.i = { 0x10000, 0x10000/5 }
}
};
@@ -49,7 +49,7 @@ const pa_envelope_def ramp_up = {
.n_points = 2,
.points_x = { 100*PA_USEC_PER_MSEC, 300*PA_USEC_PER_MSEC },
.points_y = {
- .f = { 0.2, 1.0 },
+ .f = { 0.2f, 1.0f },
.i = { 0x10000/5, 0x10000 }
}
};
@@ -58,7 +58,7 @@ const pa_envelope_def ramp_down2 = {
.n_points = 2,
.points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },
.points_y = {
- .f = { 0.8, 0.7 },
+ .f = { 0.8f, 0.7f },
.i = { 0x10000*4/5, 0x10000*7/10 }
}
};
@@ -67,7 +67,7 @@ const pa_envelope_def ramp_up2 = {
.n_points = 2,
.points_x = { 50*PA_USEC_PER_MSEC, 900*PA_USEC_PER_MSEC },
.points_y = {
- .f = { 0.7, 0.9 },
+ .f = { 0.7f, 0.9f },
.i = { 0x10000*7/10, 0x10000*9/10 }
}
};
@@ -140,7 +140,7 @@ static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss)
unsigned n_samples;
block = pa_memblock_new(pool, pa_bytes_per_second(ss));
- n_samples = pa_memblock_get_length(block) / pa_sample_size(ss);
+ n_samples = (unsigned) (pa_memblock_get_length(block) / pa_sample_size(ss));
d = pa_memblock_acquire(block);
@@ -171,7 +171,7 @@ static pa_memblock * generate_block(pa_mempool *pool, const pa_sample_spec *ss)
float *f;
for (f = d; n_samples > 0; n_samples--, f++)
- *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0);
+ *f = PA_MAYBE_FLOAT32_SWAP(ss->format == PA_SAMPLE_FLOAT32RE, 1.0f);
break;
}
@@ -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/lock-autospawn-test.c b/src/tests/lock-autospawn-test.c
new file mode 100644
index 00000000..80cfda6a
--- /dev/null
+++ b/src/tests/lock-autospawn-test.c
@@ -0,0 +1,109 @@
+/***
+ 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 <sys/poll.h>
+#include <string.h>
+
+#include <pulsecore/macro.h>
+#include <pulsecore/thread.h>
+#include <pulsecore/lock-autospawn.h>
+#include <pulse/util.h>
+
+static void thread_func(void*k) {
+ pa_assert_se(pa_autospawn_lock_init() >= 0);
+
+ pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k));
+
+ pa_assert_se(pa_autospawn_lock_acquire(TRUE) > 0);
+
+ pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k));
+
+ pa_msleep(5000);
+
+ pa_log("%i, Releasing", PA_PTR_TO_INT(k));
+
+ pa_autospawn_lock_release();
+
+ pa_autospawn_lock_done(FALSE);
+}
+
+static void thread_func2(void *k) {
+ int fd;
+
+ pa_assert_se((fd = pa_autospawn_lock_init()) >= 0);
+
+ pa_log("%i, Trying to acquire lock.", PA_PTR_TO_INT(k));
+
+ for (;;) {
+ struct pollfd pollfd;
+ int j;
+
+ if ((j = pa_autospawn_lock_acquire(FALSE)) > 0)
+ break;
+
+ pa_assert(j == 0);
+
+ memset(&pollfd, 0, sizeof(pollfd));
+ pollfd.fd = fd;
+ pollfd.events = POLLIN;
+
+ pa_assert_se(poll(&pollfd, 1, -1) == 1);
+
+ pa_log("%i, woke up", PA_PTR_TO_INT(k));
+ }
+
+ pa_log("%i, Got the lock!, Sleeping for 5s", PA_PTR_TO_INT(k));
+
+ pa_msleep(5000);
+
+ pa_log("%i, Releasing", PA_PTR_TO_INT(k));
+
+ pa_autospawn_lock_release();
+
+ pa_autospawn_lock_done(FALSE);
+}
+
+int main(int argc, char**argv) {
+ pa_thread *a, *b, *c, *d;
+
+ pa_assert_se((a = pa_thread_new(thread_func, PA_INT_TO_PTR(1))));
+ pa_assert_se((b = pa_thread_new(thread_func2, PA_INT_TO_PTR(2))));
+ pa_assert_se((c = pa_thread_new(thread_func2, PA_INT_TO_PTR(3))));
+ pa_assert_se((d = pa_thread_new(thread_func, PA_INT_TO_PTR(4))));
+
+ pa_thread_join(a);
+ pa_thread_join(b);
+ pa_thread_join(c);
+ pa_thread_join(d);
+
+ pa_thread_free(a);
+ pa_thread_free(b);
+ pa_thread_free(c);
+ pa_thread_free(d);
+
+ pa_log("End");
+
+ return 0;
+}
diff --git a/src/tests/mainloop-test.c b/src/tests/mainloop-test.c
index 9fa2e466..2580fa72 100644
--- a/src/tests/mainloop-test.c
+++ b/src/tests/mainloop-test.c
@@ -66,7 +66,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v
#endif
}
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+int main(int argc, char *argv[]) {
pa_mainloop_api *a;
pa_io_event *ioe;
pa_time_event *te;
diff --git a/src/tests/mcalign-test.c b/src/tests/mcalign-test.c
index 9e358359..92e3e14e 100644
--- a/src/tests/mcalign-test.c
+++ b/src/tests/mcalign-test.c
@@ -36,18 +36,18 @@
/* A simple program for testing pa_mcalign */
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+int main(int argc, char *argv[]) {
pa_mempool *p;
pa_mcalign *a;
pa_memchunk c;
- p = pa_mempool_new(0);
+ p = pa_mempool_new(FALSE, 0);
a = pa_mcalign_new(11);
pa_memchunk_reset(&c);
- srand(time(NULL));
+ srand((unsigned) time(NULL));
for (;;) {
ssize_t r;
@@ -62,7 +62,7 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
l = pa_memblock_get_length(c.memblock) - c.index;
- l = l <= 1 ? l : rand() % (l-1) +1 ;
+ l = l <= 1 ? l : (size_t) rand() % (l-1) +1;
p = pa_memblock_acquire(c.memblock);
@@ -74,11 +74,11 @@ int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
pa_memblock_release(c.memblock);
- c.length = r;
+ c.length = (size_t) r;
pa_mcalign_push(a, &c);
fprintf(stderr, "Read %ld bytes\n", (long)r);
- c.index += r;
+ c.index += (size_t) r;
if (c.index >= pa_memblock_get_length(c.memblock)) {
pa_memblock_unref(c.memblock);
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 f3f6f829..cc21ab03 100644
--- a/src/tests/mix-test.c
+++ b/src/tests/mix-test.c
@@ -166,16 +166,16 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
case PA_SAMPLE_FLOAT32RE: {
float *u = d;
- u[0] = 0.0;
- u[1] = -1.0;
- u[2] = 1.0;
- u[3] = 4711;
- u[4] = 0.222;
- u[5] = 0.33;
- u[6] = -.3;
- u[7] = 99;
- u[8] = -0.555;
- u[9] = -.123;
+ u[0] = 0.0f;
+ u[1] = -1.0f;
+ u[2] = 1.0f;
+ u[3] = 4711.0f;
+ u[4] = 0.222f;
+ u[5] = 0.33f;
+ u[6] = -.3f;
+ u[7] = 99.0f;
+ u[8] = -0.555f;
+ u[9] = -.123f;
if (ss->format == PA_SAMPLE_FLOAT32RE)
for (i = 0; i < 10; i++)
@@ -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/pacat-simple.c b/src/tests/pacat-simple.c
index b26e4b68..ffe3176a 100644
--- a/src/tests/pacat-simple.c
+++ b/src/tests/pacat-simple.c
@@ -33,7 +33,7 @@
#define BUFSIZE 1024
-int main(PA_GCC_UNUSED int argc, char*argv[]) {
+int main(int argc, char*argv[]) {
/* The Sample format to use */
static const pa_sample_spec ss = {
@@ -94,7 +94,7 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) {
}
/* ... and play it */
- if (pa_simple_write(s, buf, r, &error) < 0) {
+ if (pa_simple_write(s, buf, (size_t) r, &error) < 0) {
fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
goto finish;
}
diff --git a/src/tests/parec-simple.c b/src/tests/parec-simple.c
index 6c0d529b..c9d3bef5 100644
--- a/src/tests/parec-simple.c
+++ b/src/tests/parec-simple.c
@@ -47,13 +47,13 @@ static ssize_t loop_write(int fd, const void*data, size_t size) {
ret += r;
data = (const uint8_t*) data + r;
- size -= r;
+ size -= (size_t) r;
}
return ret;
}
-int main(PA_GCC_UNUSED int argc, char*argv[]) {
+int main(int argc, char*argv[]) {
/* The sample type to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
@@ -72,7 +72,6 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) {
for (;;) {
uint8_t buf[BUFSIZE];
- ssize_t r;
/* Record some data ... */
if (pa_simple_read(s, buf, sizeof(buf), &error) < 0) {
@@ -81,7 +80,7 @@ int main(PA_GCC_UNUSED int argc, char*argv[]) {
}
/* And write it to STDOUT */
- if ((r = loop_write(STDOUT_FILENO, buf, sizeof(buf))) <= 0) {
+ if (loop_write(STDOUT_FILENO, buf, sizeof(buf)) != sizeof(buf)) {
fprintf(stderr, __FILE__": write() failed: %s\n", strerror(errno));
goto finish;
}
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 1a20be2c..2d591867 100644
--- a/src/tests/resampler-test.c
+++ b/src/tests/resampler-test.c
@@ -166,16 +166,16 @@ static pa_memblock* generate_block(pa_mempool *pool, const pa_sample_spec *ss) {
case PA_SAMPLE_FLOAT32RE: {
float *u = d;
- u[0] = 0.0;
- u[1] = -1.0;
- u[2] = 1.0;
- u[3] = 4711;
- u[4] = 0.222;
- u[5] = 0.33;
- u[6] = -.3;
- u[7] = 99;
- u[8] = -0.555;
- u[9] = -.123;
+ u[0] = 0.0f;
+ u[1] = -1.0f;
+ u[2] = 1.0f;
+ u[3] = 4711.0f;
+ u[4] = 0.222f;
+ u[5] = 0.33f;
+ u[6] = -.3f;
+ u[7] = 99.0f;
+ u[8] = -0.555f;
+ u[9] = -.123f;
if (ss->format == PA_SAMPLE_FLOAT32RE)
for (i = 0; i < 10; i++)
@@ -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/rtstutter.c b/src/tests/rtstutter.c
index 91e85c36..6b0cb8f7 100644
--- a/src/tests/rtstutter.c
+++ b/src/tests/rtstutter.c
@@ -52,7 +52,7 @@ static void* work(void *p) {
pa_assert_se(pthread_setschedparam(pthread_self(), SCHED_FIFO, &param) == 0);
CPU_ZERO(&mask);
- CPU_SET(PA_PTR_TO_INT(p), &mask);
+ CPU_SET((size_t) PA_PTR_TO_INT(p), &mask);
pa_assert_se(pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) == 0);
for (;;) {
@@ -65,17 +65,17 @@ static void* work(void *p) {
pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0);
nsec =
- (uint64_t) ((((double) rand())*(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) +
- (uint64_t) (msec_lower*PA_NSEC_PER_MSEC);
+ (uint64_t) ((((double) rand())*(double)(msec_upper-msec_lower)*PA_NSEC_PER_MSEC)/RAND_MAX) +
+ (uint64_t) ((uint64_t) msec_lower*PA_NSEC_PER_MSEC);
pa_log_notice("CPU%i: Freezing for %ims", PA_PTR_TO_INT(p), (int) (nsec/PA_NSEC_PER_MSEC));
- end.tv_sec += nsec / PA_NSEC_PER_SEC;
- end.tv_nsec += nsec % PA_NSEC_PER_SEC;
+ end.tv_sec += (time_t) (nsec / PA_NSEC_PER_SEC);
+ end.tv_nsec += (long int) (nsec % PA_NSEC_PER_SEC);
while ((pa_usec_t) end.tv_nsec > PA_NSEC_PER_SEC) {
end.tv_sec++;
- end.tv_nsec -= PA_NSEC_PER_SEC;
+ end.tv_nsec -= (long int) PA_NSEC_PER_SEC;
}
do {
@@ -88,7 +88,7 @@ static void* work(void *p) {
int main(int argc, char*argv[]) {
int n;
- srand(time(NULL));
+ srand((unsigned) time(NULL));
if (argc >= 3) {
msec_lower = atoi(argv[1]);
diff --git a/src/tests/smoother-test.c b/src/tests/smoother-test.c
index b78f3c91..15700ec2 100644
--- a/src/tests/smoother-test.c
+++ b/src/tests/smoother-test.c
@@ -64,7 +64,7 @@ int main(int argc, char*argv[]) {
for (x = 0, u = 0; x < PA_USEC_PER_SEC * 10; x += PA_USEC_PER_MSEC) {
while (u < PA_ELEMENTSOF(msec) && (pa_usec_t) msec[u]*PA_USEC_PER_MSEC < x) {
- pa_smoother_put(s, msec[u]*PA_USEC_PER_MSEC, msec[u+1]*PA_USEC_PER_MSEC);
+ pa_smoother_put(s, (pa_usec_t) msec[u] * PA_USEC_PER_MSEC, (pa_usec_t) msec[u+1] * PA_USEC_PER_MSEC);
printf("%i\t\t%i\n", msec[u], msec[u+1]);
u += 2;
}
diff --git a/src/tests/stripnul.c b/src/tests/stripnul.c
index 0ab06776..2b8aa083 100644
--- a/src/tests/stripnul.c
+++ b/src/tests/stripnul.c
@@ -35,7 +35,7 @@ int main(int argc, char *argv[]) {
uint8_t *zero;
pa_assert_se(argc >= 2);
- pa_assert_se((granularity = atoi(argv[1])) >= 1);
+ pa_assert_se((granularity = (size_t) atoi(argv[1])) >= 1);
pa_assert_se((i = (argc >= 3) ? fopen(argv[2], "r") : stdin));
pa_assert_se((o = (argc >= 4) ? fopen(argv[3], "w") : stdout));
@@ -53,11 +53,11 @@ int main(int argc, char *argv[]) {
if (found)
pa_assert_se(fwrite(buffer, granularity, k, o) == k);
else {
- for (p = buffer; (p-buffer)/granularity < k; p += granularity)
+ for (p = buffer; ((size_t) (p-buffer)/granularity) < k; p += granularity)
if (memcmp(p, zero, granularity)) {
size_t left;
found = TRUE;
- left = k - (p-buffer)/granularity;
+ left = (size_t) (k - (size_t) (p-buffer)/granularity);
pa_assert_se(fwrite(p, granularity, left, o) == left);
break;
}
diff --git a/src/tests/strlist-test.c b/src/tests/strlist-test.c
index 2bd1645c..10f370c2 100644
--- a/src/tests/strlist-test.c
+++ b/src/tests/strlist-test.c
@@ -5,7 +5,7 @@
#include <pulsecore/strlist.h>
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char* argv[]) {
+int main(int argc, char* argv[]) {
char *t, *u;
pa_strlist *l = NULL;
diff --git a/src/tests/sync-playback.c b/src/tests/sync-playback.c
index 7e364685..42c479a1 100644
--- a/src/tests/sync-playback.c
+++ b/src/tests/sync-playback.c
@@ -89,7 +89,7 @@ static void stream_state_callback(pa_stream *s, void *userdata) {
fprintf(stderr, "Writing data to stream %i.\n", i);
- r = pa_stream_write(s, data, sizeof(data), nop_free_cb, sizeof(data) * i, PA_SEEK_ABSOLUTE);
+ r = pa_stream_write(s, data, sizeof(data), nop_free_cb, (int64_t) sizeof(data) * (int64_t) i, PA_SEEK_ABSOLUTE);
assert(r == 0);
/* Be notified when this stream is drained */
diff --git a/src/tests/thread-mainloop-test.c b/src/tests/thread-mainloop-test.c
index 7a62f85a..263cd57d 100644
--- a/src/tests/thread-mainloop-test.c
+++ b/src/tests/thread-mainloop-test.c
@@ -39,7 +39,7 @@ static void tcb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *tv, v
fprintf(stderr, "TIME EVENT END\n");
}
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+int main(int argc, char *argv[]) {
pa_mainloop_api *a;
pa_threaded_mainloop *m;
struct timeval tv;
diff --git a/src/tests/voltest.c b/src/tests/voltest.c
index d2c0ff69..5bfc97e0 100644
--- a/src/tests/voltest.c
+++ b/src/tests/voltest.c
@@ -3,8 +3,9 @@
#include <pulse/volume.h>
#include <pulse/gccmacro.h>
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) {
+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(PA_GCC_UNUSED int argc, PA_GCC_UNUSED 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/pacat.c b/src/utils/pacat.c
index 32fa6bcf..ea736e23 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -57,6 +57,7 @@ static char *stream_name = NULL, *client_name = NULL, *device = NULL;
static int verbose = 0;
static pa_volume_t volume = PA_VOLUME_NORM;
+static int volume_is_set = 0;
static pa_sample_spec sample_spec = {
.format = PA_SAMPLE_S16LE,
@@ -274,8 +275,8 @@ static void context_state_callback(pa_context *c, void *userdata) {
if (latency > 0) {
memset(&buffer_attr, 0, sizeof(buffer_attr));
- buffer_attr.tlength = latency;
- buffer_attr.minreq = process_time;
+ buffer_attr.tlength = (uint32_t) latency;
+ buffer_attr.minreq = (uint32_t) process_time;
buffer_attr.maxlength = (uint32_t) -1;
buffer_attr.prebuf = (uint32_t) -1;
flags |= PA_STREAM_ADJUST_LATENCY;
@@ -283,7 +284,7 @@ static void context_state_callback(pa_context *c, void *userdata) {
if (mode == PLAYBACK) {
pa_cvolume cv;
- if ((r = pa_stream_connect_playback(stream, device, latency > 0 ? &buffer_attr : NULL, flags, pa_cvolume_set(&cv, sample_spec.channels, volume), NULL)) < 0) {
+ if ((r = pa_stream_connect_playback(stream, device, latency > 0 ? &buffer_attr : NULL, flags, volume_is_set ? pa_cvolume_set(&cv, sample_spec.channels, volume) : NULL, NULL)) < 0) {
fprintf(stderr, _("pa_stream_connect_playback() failed: %s\n"), pa_strerror(pa_context_errno(c)));
goto fail;
}
@@ -391,7 +392,7 @@ static void stdin_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_even
return;
}
- buffer_length = r;
+ buffer_length = (uint32_t) r;
buffer_index = 0;
if (w)
@@ -422,8 +423,8 @@ static void stdout_callback(pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_eve
return;
}
- buffer_length -= r;
- buffer_index += r;
+ buffer_length -= (uint32_t) r;
+ buffer_index += (uint32_t) r;
if (!buffer_length) {
pa_xfree(buffer);
@@ -456,7 +457,7 @@ static void stream_update_timing_callback(pa_stream *s, int success, void *userd
fprintf(stderr, _("Time: %0.3f sec; Latency: %0.0f usec. \r"),
(float) usec / 1000000,
- (float) l * (negative?-1:1));
+ (float) l * (negative?-1.0f:1.0f));
}
/* Someone requested that the latency is shown */
@@ -500,7 +501,7 @@ static void help(const char *argv0) {
" --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"
+ " 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"
@@ -626,12 +627,13 @@ int main(int argc, char *argv[]) {
case ARG_VOLUME: {
int v = atoi(optarg);
- volume = v < 0 ? 0 : v;
+ volume = v < 0 ? 0U : (pa_volume_t) v;
+ volume_is_set = 1;
break;
}
case ARG_CHANNELS:
- sample_spec.channels = atoi(optarg);
+ sample_spec.channels = (uint8_t) atoi(optarg);
break;
case ARG_SAMPLEFORMAT:
@@ -639,7 +641,7 @@ int main(int argc, char *argv[]) {
break;
case ARG_SAMPLERATE:
- sample_spec.rate = atoi(optarg);
+ sample_spec.rate = (uint32_t) atoi(optarg);
break;
case ARG_CHANNELMAP:
@@ -672,14 +674,14 @@ int main(int argc, char *argv[]) {
break;
case ARG_LATENCY:
- if (((latency = atoi(optarg))) <= 0) {
+ if (((latency = (size_t) atoi(optarg))) <= 0) {
fprintf(stderr, _("Invalid latency specification '%s'\n"), optarg);
goto quit;
}
break;
case ARG_PROCESS_TIME:
- if (((process_time = atoi(optarg))) <= 0) {
+ if (((process_time = (size_t) atoi(optarg))) <= 0) {
fprintf(stderr, _("Invalid process time specification '%s'\n"), optarg);
goto quit;
}
@@ -695,7 +697,7 @@ int main(int argc, char *argv[]) {
goto quit;
}
- if (channel_map_set && channel_map.channels != sample_spec.channels) {
+ if (channel_map_set && pa_channel_map_compatible(&channel_map, &sample_spec)) {
fprintf(stderr, _("Channel map doesn't match sample specification\n"));
goto quit;
}
@@ -773,7 +775,10 @@ int main(int argc, char *argv[]) {
pa_context_set_state_callback(context, context_state_callback, NULL);
/* Connect the context */
- pa_context_connect(context, server, 0, NULL);
+ if (pa_context_connect(context, server, 0, NULL) < 0) {
+ fprintf(stderr, _("pa_context_connect() failed: %s"), pa_strerror(pa_context_errno(context)));
+ goto quit;
+ }
if (verbose) {
struct timeval tv;
diff --git a/src/utils/pacmd.c b/src/utils/pacmd.c
index 24cddaa3..2c89c8d9 100644
--- a/src/utils/pacmd.c
+++ b/src/utils/pacmd.c
@@ -42,7 +42,7 @@
#include <pulsecore/log.h>
#include <pulsecore/pid.h>
-int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char*argv[]) {
+int main(int argc, char*argv[]) {
pid_t pid ;
int fd = -1;
int ret = 1, i;
diff --git a/src/utils/pactl.c b/src/utils/pactl.c
index 3f00df1b..2f430ca7 100644
--- a/src/utils/pactl.c
+++ b/src/utils/pactl.c
@@ -555,7 +555,7 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {
d = pa_xmalloc(length);
assert(sample_length >= length);
- l = length/pa_frame_size(&sample_spec);
+ l = (sf_count_t) (length/pa_frame_size(&sample_spec));
if ((sf_readf_float(sndfile, d, l)) != l) {
pa_xfree(d);
@@ -791,11 +791,11 @@ int main(int argc, char *argv[]) {
goto quit;
}
- sample_spec.format = PA_SAMPLE_FLOAT32;
- sample_spec.rate = sfinfo.samplerate;
- sample_spec.channels = sfinfo.channels;
+ sample_spec.format = PA_SAMPLE_FLOAT32;
+ sample_spec.rate = (uint32_t) sfinfo.samplerate;
+ sample_spec.channels = (uint8_t) sfinfo.channels;
- sample_length = sfinfo.frames*pa_frame_size(&sample_spec);
+ sample_length = (size_t)sfinfo.frames*pa_frame_size(&sample_spec);
} else if (!strcmp(argv[optind], "play-sample")) {
action = PLAY_SAMPLE;
if (argc != optind+2 && argc != optind+3) {
@@ -823,7 +823,7 @@ int main(int argc, char *argv[]) {
goto quit;
}
- sink_input_idx = atoi(argv[optind+1]);
+ sink_input_idx = (uint32_t) atoi(argv[optind+1]);
sink_name = pa_xstrdup(argv[optind+2]);
} else if (!strcmp(argv[optind], "move-source-output")) {
action = MOVE_SOURCE_OUTPUT;
@@ -832,7 +832,7 @@ int main(int argc, char *argv[]) {
goto quit;
}
- source_output_idx = atoi(argv[optind+1]);
+ source_output_idx = (uint32_t) atoi(argv[optind+1]);
source_name = pa_xstrdup(argv[optind+2]);
} else if (!strcmp(argv[optind], "load-module")) {
int i;
@@ -852,7 +852,7 @@ int main(int argc, char *argv[]) {
n += strlen(argv[i])+1;
if (n > 0) {
- p = module_args = pa_xnew0(char, n);
+ p = module_args = pa_xmalloc(n);
for (i = optind+2; i < argc; i++)
p += sprintf(p, "%s%s", p == module_args ? "" : " ", argv[i]);
@@ -866,7 +866,7 @@ int main(int argc, char *argv[]) {
goto quit;
}
- module_index = atoi(argv[optind+1]);
+ module_index = (uint32_t) atoi(argv[optind+1]);
} else if (!strcmp(argv[optind], "suspend-sink")) {
action = SUSPEND_SINK;
diff --git a/src/utils/padsp.c b/src/utils/padsp.c
index c82fde64..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;
}
@@ -748,7 +749,7 @@ static void fix_metrics(fd_info *i) {
/* Number of fragments set? */
if (i->n_fragments < 2) {
if (i->fragment_size > 0) {
- i->n_fragments = pa_bytes_per_second(&i->sample_spec) / 2 / i->fragment_size;
+ i->n_fragments = (unsigned) (pa_bytes_per_second(&i->sample_spec) / 2 / i->fragment_size);
if (i->n_fragments < 2)
i->n_fragments = 2;
} else
@@ -864,7 +865,7 @@ static int fd_info_copy_data(fd_info *i, int force) {
return -1;
}
- if (pa_stream_write(i->play_stream, i->buf, r, free, 0, PA_SEEK_RELATIVE) < 0) {
+ if (pa_stream_write(i->play_stream, i->buf, (size_t) r, free, 0LL, PA_SEEK_RELATIVE) < 0) {
debug(DEBUG_LEVEL_NORMAL, __FILE__": pa_stream_write(): %s\n", pa_strerror(pa_context_errno(i->context)));
return -1;
}
@@ -872,7 +873,7 @@ static int fd_info_copy_data(fd_info *i, int force) {
i->buf = NULL;
assert(n >= (size_t) r);
- n -= r;
+ n -= (size_t) r;
}
if (n >= i->fragment_size)
@@ -916,7 +917,7 @@ static int fd_info_copy_data(fd_info *i, int force) {
}
assert((size_t)r <= len - i->rec_offset);
- i->rec_offset += r;
+ i->rec_offset += (size_t) r;
if (i->rec_offset == len) {
if (pa_stream_drop(i->rec_stream) < 0) {
@@ -927,7 +928,7 @@ static int fd_info_copy_data(fd_info *i, int force) {
}
assert(n >= (size_t) r);
- n -= r;
+ n -= (size_t) r;
}
if (n >= i->fragment_size)
@@ -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;
}
@@ -998,12 +1003,12 @@ static int create_playback_stream(fd_info *i) {
pa_stream_set_latency_update_callback(i->play_stream, stream_latency_update_cb, i);
memset(&attr, 0, sizeof(attr));
- attr.maxlength = i->fragment_size * (i->n_fragments+1);
- attr.tlength = i->fragment_size * i->n_fragments;
- attr.prebuf = i->fragment_size;
- attr.minreq = i->fragment_size;
+ attr.maxlength = (uint32_t) (i->fragment_size * (i->n_fragments+1));
+ attr.tlength = (uint32_t) (i->fragment_size * i->n_fragments);
+ attr.prebuf = (uint32_t) i->fragment_size;
+ attr.minreq = (uint32_t) i->fragment_size;
- flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;
+ flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE|PA_STREAM_EARLY_REQUESTS;
if (i->play_precork) {
flags |= PA_STREAM_START_CORKED;
debug(DEBUG_LEVEL_NORMAL, __FILE__": creating stream corked\n");
@@ -1013,9 +1018,9 @@ static int create_playback_stream(fd_info *i) {
goto fail;
}
- n = i->fragment_size;
+ n = (int) i->fragment_size;
setsockopt(i->app_fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n));
- n = i->fragment_size;
+ n = (int) i->fragment_size;
setsockopt(i->thread_fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));
return 0;
@@ -1042,8 +1047,8 @@ static int create_record_stream(fd_info *i) {
pa_stream_set_latency_update_callback(i->rec_stream, stream_latency_update_cb, i);
memset(&attr, 0, sizeof(attr));
- attr.maxlength = i->fragment_size * (i->n_fragments+1);
- attr.fragsize = i->fragment_size;
+ attr.maxlength = (uint32_t) (i->fragment_size * (i->n_fragments+1));
+ attr.fragsize = (uint32_t) i->fragment_size;
flags = PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;
if (i->rec_precork) {
@@ -1055,9 +1060,9 @@ static int create_record_stream(fd_info *i) {
goto fail;
}
- n = i->fragment_size;
+ n = (int) i->fragment_size;
setsockopt(i->app_fd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));
- n = i->fragment_size;
+ n = (int) i->fragment_size;
setsockopt(i->thread_fd, SOL_SOCKET, SO_SNDBUF, &n, sizeof(n));
return 0;
@@ -1474,7 +1479,7 @@ int open(const char *filename, int flags, ...) {
if (flags & O_CREAT) {
va_start(args, flags);
if (sizeof(mode_t) < sizeof(int))
- mode = va_arg(args, int);
+ mode = (mode_t) va_arg(args, int);
else
mode = va_arg(args, mode_t);
va_end(args);
diff --git a/src/utils/paplay.c b/src/utils/paplay.c
index 9264a940..df2edf62 100644
--- a/src/utils/paplay.c
+++ b/src/utils/paplay.c
@@ -107,14 +107,14 @@ static void stream_write_callback(pa_stream *s, size_t length, void *userdata) {
if (readf_function) {
size_t k = pa_frame_size(&sample_spec);
- if ((bytes = readf_function(sndfile, data, length/k)) > 0)
- bytes *= k;
+ if ((bytes = readf_function(sndfile, data, (sf_count_t) (length/k))) > 0)
+ bytes *= (sf_count_t) k;
} else
- bytes = sf_read_raw(sndfile, data, length);
+ bytes = sf_read_raw(sndfile, data, (sf_count_t) length);
if (bytes > 0)
- pa_stream_write(s, data, bytes, pa_xfree, 0, PA_SEEK_RELATIVE);
+ pa_stream_write(s, data, (size_t) bytes, pa_xfree, 0, PA_SEEK_RELATIVE);
else
pa_xfree(data);
@@ -283,7 +283,7 @@ int main(int argc, char *argv[]) {
case ARG_VOLUME: {
int v = atoi(optarg);
- volume = v < 0 ? 0 : v;
+ volume = v < 0 ? 0U : (pa_volume_t) v;
break;
}
@@ -315,8 +315,8 @@ int main(int argc, char *argv[]) {
goto quit;
}
- sample_spec.rate = sfinfo.samplerate;
- sample_spec.channels = sfinfo.channels;
+ sample_spec.rate = (uint32_t) sfinfo.samplerate;
+ sample_spec.channels = (uint8_t) sfinfo.channels;
readf_function = NULL;