summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2020-02-19 18:32:27 +0100
committerSebastien Bacher <seb128@ubuntu.com>2020-02-20 15:24:34 +0100
commitb95cf1075e28f266a3af795f8ecbd74e606e9ebd (patch)
treeb6380320d5f75a9cc2cea707f95785a08ff051db
parenta003359ee4da70b85db93f50ab3f013a08bbd63f (diff)
parentbb5f82cb41d3d34eb11e13cb19bec99ab276d142 (diff)
Update upstream source from tag 'upstream/13.99.1'
Update to upstream version '13.99.1' with Debian dir 0836e984298802a1852083259fe694e7f27afe82
-rw-r--r--.gitlab-ci.yml94
-rw-r--r--.tarball-version2
-rw-r--r--.version2
-rw-r--r--Makefile.am3
-rw-r--r--Makefile.in8
-rw-r--r--NEWS16
-rwxr-xr-xbuild-aux/config.guess128
-rwxr-xr-xbuild-aux/config.sub2455
-rw-r--r--build-aux/ltmain.sh246
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure376
-rw-r--r--configure.ac20
-rw-r--r--debian/changelog16
-rw-r--r--debian/control2
-rw-r--r--debian/patches/daemon-conf-disable-flat-volumes-by-default.patch57
-rw-r--r--debian/patches/qpaeq-Drop-unused-imports.patch22
-rw-r--r--debian/patches/qpaeq-use-python3-instead-of-python-2.patch20
-rw-r--r--debian/patches/series3
-rw-r--r--doxygen/Makefile.in3
-rw-r--r--m4/gettext.m439
-rw-r--r--m4/iconv.m463
-rw-r--r--m4/intlmacosx.m46
-rw-r--r--m4/lib-ld.m42
-rw-r--r--m4/lib-link.m42
-rw-r--r--m4/lib-prefix.m42
-rw-r--r--m4/libtool.m448
-rw-r--r--m4/nls.m42
-rw-r--r--m4/po.m48
-rw-r--r--m4/progtest.m46
-rw-r--r--man/Makefile.in3
-rw-r--r--man/default.pa.56
-rw-r--r--man/pax11publish.12
-rw-r--r--man/pulse-cli-syntax.54
-rw-r--r--man/pulse-client.conf.56
-rw-r--r--man/pulse-daemon.conf.518
-rw-r--r--man/pulse-daemon.conf.5.xml.in40
-rw-r--r--man/pulseaudio.122
-rw-r--r--man/pulseaudio.1.xml.in51
-rw-r--r--meson.build18
-rw-r--r--meson_options.txt7
-rw-r--r--po/POTFILES.in4
-rw-r--r--po/as.gmobin53998 -> 54039 bytes
-rw-r--r--po/be.gmobin85822 -> 85863 bytes
-rw-r--r--po/bn_IN.gmobin57410 -> 57451 bytes
-rw-r--r--po/cs.gmobin70217 -> 70258 bytes
-rw-r--r--po/de.gmobin68462 -> 68503 bytes
-rw-r--r--po/de_CH.gmobin33445 -> 33486 bytes
-rw-r--r--po/el.gmobin89644 -> 89685 bytes
-rw-r--r--po/fi.gmobin38315 -> 38356 bytes
-rw-r--r--po/fr.gmobin70198 -> 70239 bytes
-rw-r--r--po/gu.gmobin54381 -> 54422 bytes
-rw-r--r--po/he.gmobin5468 -> 5509 bytes
-rw-r--r--po/hi.gmobin50618 -> 50659 bytes
-rw-r--r--po/hr.gmobin69761 -> 69916 bytes
-rw-r--r--po/hr.po218
-rw-r--r--po/hu.gmobin72626 -> 72667 bytes
-rw-r--r--po/id.gmobin63424 -> 63465 bytes
-rw-r--r--po/it.gmobin71388 -> 71775 bytes
-rw-r--r--po/it.po109
-rw-r--r--po/ja.gmobin69881 -> 69922 bytes
-rw-r--r--po/kn.gmobin60196 -> 60237 bytes
-rw-r--r--po/ko.gmobin69174 -> 69215 bytes
-rw-r--r--po/mr.gmobin51720 -> 51761 bytes
-rw-r--r--po/nl.gmobin37352 -> 37393 bytes
-rw-r--r--po/nn.gmobin66450 -> 66491 bytes
-rw-r--r--po/oc.gmobin44421 -> 44462 bytes
-rw-r--r--po/or.gmobin53389 -> 53430 bytes
-rw-r--r--po/pa.gmobin49585 -> 49626 bytes
-rw-r--r--po/pt.gmobin36025 -> 36066 bytes
-rw-r--r--po/pulseaudio.pot540
-rw-r--r--po/sk.gmobin26723 -> 26764 bytes
-rw-r--r--po/sr.gmobin47269 -> 47310 bytes
-rw-r--r--po/sr@latin.gmobin37951 -> 37992 bytes
-rw-r--r--po/ta.gmobin54834 -> 54875 bytes
-rw-r--r--po/te.gmobin57458 -> 57499 bytes
-rw-r--r--po/tr.gmobin68354 -> 68395 bytes
-rw-r--r--po/zh_CN.gmobin62367 -> 62408 bytes
-rw-r--r--po/zh_TW.gmobin64926 -> 65186 bytes
-rw-r--r--po/zh_TW.po1484
-rw-r--r--scripts/Dockerfile65
-rw-r--r--shell-completion/bash/meson.build34
-rw-r--r--shell-completion/bash/pulseaudio15
-rw-r--r--shell-completion/zsh/meson.build4
-rw-r--r--src/Makefile.am32
-rw-r--r--src/Makefile.in410
-rw-r--r--src/daemon/daemon-conf.c59
-rw-r--r--src/daemon/daemon-conf.h4
-rw-r--r--src/daemon/daemon.conf.in7
-rwxr-xr-xsrc/daemon/default.pa.in4
-rw-r--r--src/daemon/main.c4
-rw-r--r--src/daemon/meson.build2
-rwxr-xr-xsrc/daemon/start-pulseaudio-x11.in12
-rwxr-xr-xsrc/daemon/system.pa.in4
-rw-r--r--src/meson.build2
-rw-r--r--src/modules/alsa/90-pulseaudio.rules22
-rw-r--r--src/modules/alsa/alsa-mixer.c370
-rw-r--r--src/modules/alsa/alsa-mixer.h33
-rw-r--r--src/modules/alsa/alsa-sink.c103
-rw-r--r--src/modules/alsa/alsa-source.c90
-rw-r--r--src/modules/alsa/alsa-ucm.c618
-rw-r--r--src/modules/alsa/alsa-ucm.h87
-rw-r--r--src/modules/alsa/alsa-util.c184
-rw-r--r--src/modules/alsa/alsa-util.h11
-rw-r--r--src/modules/alsa/meson.build2
-rw-r--r--src/modules/alsa/mixer/paths/analog-output-speaker.conf3
-rw-r--r--src/modules/alsa/mixer/paths/analog-output.conf.common3
-rw-r--r--src/modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf (renamed from src/modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf)0
-rw-r--r--src/modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf (renamed from src/modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf)0
-rw-r--r--src/modules/alsa/mixer/paths/usb-gaming-headset-input.conf (renamed from src/modules/alsa/mixer/paths/steelseries-arctis-7-input.conf)12
-rw-r--r--src/modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf (renamed from src/modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf)15
-rw-r--r--src/modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf (renamed from src/modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf)15
-rw-r--r--src/modules/alsa/mixer/profile-sets/default.conf6
-rw-r--r--src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf (renamed from src/modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf)5
-rw-r--r--src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf (renamed from src/modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf)20
-rw-r--r--src/modules/alsa/module-alsa-card.c132
-rw-r--r--src/modules/alsa/module-alsa-sink.c2
-rw-r--r--src/modules/alsa/module-alsa-source.c2
-rw-r--r--src/modules/bluetooth/meson.build2
-rw-r--r--src/modules/bluetooth/module-bluez5-device.c37
-rw-r--r--src/modules/echo-cancel/meson.build2
-rw-r--r--src/modules/echo-cancel/module-echo-cancel.c8
-rw-r--r--src/modules/gsettings/meson.build2
-rw-r--r--src/modules/gsettings/meson_post_install.py14
-rwxr-xr-xsrc/modules/gsettings/post-install.sh12
-rw-r--r--src/modules/jack/module-jackdbus-detect.c28
-rw-r--r--src/modules/meson.build4
-rw-r--r--src/modules/module-card-restore.c3
-rw-r--r--src/modules/module-device-manager.c18
-rw-r--r--src/modules/module-filter-apply.c6
-rw-r--r--src/modules/module-intended-roles.c14
-rw-r--r--src/modules/module-null-sink.c2
-rw-r--r--src/modules/module-remap-source.c8
-rw-r--r--src/modules/module-rescue-streams.c315
-rw-r--r--src/modules/module-stream-restore.c322
-rw-r--r--src/modules/module-switch-on-connect.c85
-rw-r--r--src/modules/module-virtual-source.c23
-rw-r--r--src/modules/module-virtual-surround-sink.c2
-rw-r--r--src/modules/raop/meson.build2
-rw-r--r--src/modules/raop/module-raop-sink.c2
-rw-r--r--src/modules/raop/raop-client.c60
-rw-r--r--src/modules/raop/raop-client.h5
-rw-r--r--src/modules/raop/raop-sink.c288
-rw-r--r--src/modules/rtp/meson.build10
-rw-r--r--src/modules/rtp/module-rtp-recv.c48
-rw-r--r--src/modules/rtp/module-rtp-send.c17
-rw-r--r--src/modules/rtp/rtp-common.c97
-rw-r--r--src/modules/rtp/rtp-gstreamer.c524
-rw-r--r--src/modules/rtp/rtp-native.c (renamed from src/modules/rtp/rtp.c)194
-rw-r--r--src/modules/rtp/rtp.h28
-rw-r--r--src/modules/rtp/rtsp_client.c40
-rw-r--r--src/modules/rtp/rtsp_client.h2
-rw-r--r--src/modules/rtp/sdp.c9
-rw-r--r--src/modules/x11/module-x11-bell.c8
-rw-r--r--src/modules/x11/module-x11-cork-request.c8
-rw-r--r--src/modules/x11/module-x11-publish.c8
-rw-r--r--src/modules/x11/module-x11-xsmp.c8
-rw-r--r--src/pulse/context.c1
-rw-r--r--src/pulse/gccmacro.h38
-rw-r--r--src/pulse/meson.build6
-rw-r--r--src/pulse/stream.h4
-rw-r--r--src/pulse/version.h4
-rw-r--r--src/pulsecore/atomic.h2
-rw-r--r--src/pulsecore/core-util.c50
-rw-r--r--src/pulsecore/core-util.h3
-rw-r--r--src/pulsecore/core.c77
-rw-r--r--src/pulsecore/core.h8
-rw-r--r--src/pulsecore/device-port.c50
-rw-r--r--src/pulsecore/device-port.h4
-rw-r--r--src/pulsecore/macro.h38
-rw-r--r--src/pulsecore/meson.build2
-rw-r--r--src/pulsecore/resampler.c4
-rw-r--r--src/pulsecore/resampler.h3
-rw-r--r--src/pulsecore/rtpoll.c63
-rw-r--r--src/pulsecore/rtpoll.h9
-rw-r--r--src/pulsecore/sink-input.c57
-rw-r--r--src/pulsecore/sink-input.h19
-rw-r--r--src/pulsecore/sink.c53
-rw-r--r--src/pulsecore/sink.h6
-rw-r--r--src/pulsecore/source-output.c57
-rw-r--r--src/pulsecore/source-output.h19
-rw-r--r--src/pulsecore/source.c52
-rw-r--r--src/pulsecore/source.h6
-rw-r--r--src/tests/alsa-mixer-path-test.c5
-rw-r--r--src/tests/meson.build4
-rw-r--r--src/tests/remix-test.c10
-rw-r--r--src/tests/rtpoll-test.c10
-rw-r--r--src/utils/meson.build8
-rwxr-xr-xsrc/utils/qpaeq3
188 files changed, 6737 insertions, 4782 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0c00925..dcb4a98 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,91 @@
-image: registry.freedesktop.org/pulseaudio/pulseaudio/ubuntu:18.04
+# The build has two stages. The 'container' stage is used to build a Docker
+# container and push it to the project's container registry on fd.o GitLab.
+# This step is only run when the tag for the container changes, else it is
+# effectively a no-op. All of this infrastructure is inherited from the
+# wayland/ci-templates repository which is the recommended way to set up CI
+# infrastructure on fd.o GitLab.
+#
+# Once the container stage is done, we move on to the 'build' stage where we
+# run an autotools and meson build in parallel. Currently, tests are also run
+# as part of the build stage as there doesn't seem to be significant value to
+# splitting the stages at the moment.
+
+stages:
+ - container
+ - build
+
+variables:
+ # Update this tag when you want to trigger a rebuild the container in which
+ # CI runs, for example when adding new packages to UBUNTU_DEBS. The tag is
+ # an arbitrary string that identifies the exact container contents.
+ UBUNTU_TAG: '2019-11-21-01'
+ UBUNTU_VERSION: '18.04'
+ UBUNTU_IMAGE: "$CI_REGISTRY_IMAGE/ubuntu/$UBUNTU_VERSION:$UBUNTU_TAG"
+
+include:
+ - project: 'wayland/ci-templates'
+ ref: master
+ file: '/templates/ubuntu.yml'
+
+build-container:
+ extends: .ubuntu@container-ifnot-exists
+ stage: container
+ variables:
+ GIT_STRATEGY: none # no need to pull the whole tree for rebuilding the image
+
+ # Remember to update UBUNTU_TAG when modifying this package list! Otherwise
+ # the changes won't have effect since an old container image will be used.
+ UBUNTU_DEBS: >-
+ autoconf
+ automake
+ autopoint
+ bash-completion
+ check
+ curl
+ dbus-x11
+ g++
+ gcc
+ gettext
+ git-core
+ libasound2-dev
+ libasyncns-dev
+ libavahi-client-dev
+ libbluetooth-dev
+ libcap-dev
+ libfftw3-dev
+ libglib2.0-dev
+ libgtk-3-dev
+ libice-dev
+ libjack-dev
+ liblircclient-dev
+ libltdl-dev
+ liborc-0.4-dev
+ libsbc-dev
+ libsndfile1-dev
+ libsoxr-dev
+ libspeexdsp-dev
+ libssl-dev
+ libsystemd-dev
+ libtdb-dev
+ libtool
+ libudev-dev
+ libwebrtc-audio-processing-dev
+ libwrap0-dev
+ libx11-xcb-dev
+ libxcb1-dev
+ libxml-parser-perl
+ libxml2-utils
+ libxtst-dev
+ make
+ ninja-build
+ pkg-config
+ python3-setuptools
+ systemd
+ wget
build-autotools:
stage: build
+ image: $UBUNTU_IMAGE
script:
- export MAKEFLAGS="-j$(nproc)"
- NOCONFIGURE=1 ./bootstrap.sh
@@ -19,7 +103,15 @@ build-autotools:
build-meson:
stage: build
+ image: $UBUNTU_IMAGE
script:
+ # Install meson
+ - wget -q https://github.com/mesonbuild/meson/releases/download/0.50.0/meson-0.50.0.tar.gz
+ - tar -xf meson-0.50.0.tar.gz
+ - cd meson-0.50.0
+ - python3 setup.py install
+ - cd ..
+ # Do the actual build
- meson build
- cd build
- ninja
diff --git a/.tarball-version b/.tarball-version
index f075061..99bc3d6 100644
--- a/.tarball-version
+++ b/.tarball-version
@@ -1 +1 @@
-13.0
+13.99.1
diff --git a/.version b/.version
index f075061..99bc3d6 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-13.0
+13.99.1
diff --git a/Makefile.am b/Makefile.am
index 7784135..1cca140 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,7 +32,6 @@ EXTRA_DIST = \
README \
CODE_OF_CONDUCT.md \
scripts/benchmark_memory_usage.sh \
- scripts/Dockerfile \
scripts/plot_memory_usage.gp \
scripts/benchmarks/README \
todo \
@@ -58,7 +57,7 @@ EXTRA_DIST = \
src/modules/bluetooth/meson.build \
src/modules/echo-cancel/meson.build \
src/modules/gsettings/meson.build \
- src/modules/gsettings/post-install.sh \
+ src/modules/gsettings/meson_post_install.py \
src/modules/meson.build \
src/modules/oss/meson.build \
src/modules/raop/meson.build \
diff --git a/Makefile.in b/Makefile.in
index 3e18b95..6e9da6c 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -240,7 +240,7 @@ am__DIST_COMMON = $(srcdir)/Makefile.in \
$(top_srcdir)/build-aux/missing \
$(top_srcdir)/src/pulse/version.h.in ABOUT-NLS NEWS README \
build-aux/compile build-aux/config.guess \
- build-aux/config.rpath build-aux/config.sub \
+ build-aux/config.rpath build-aux/config.sub build-aux/depcomp \
build-aux/install-sh build-aux/ltmain.sh build-aux/missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
@@ -342,6 +342,8 @@ GREP = @GREP@
GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@
GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@
GSETTINGS_LIBS = @GSETTINGS_LIBS@
+GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@
+GSTREAMER_LIBS = @GSTREAMER_LIBS@
GTK30_CFLAGS = @GTK30_CFLAGS@
GTK30_LIBS = @GTK30_LIBS@
HAVE_AF_UNIX = @HAVE_AF_UNIX@
@@ -552,7 +554,6 @@ prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pulseconfdir = @pulseconfdir@
-runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -582,7 +583,6 @@ EXTRA_DIST = \
README \
CODE_OF_CONDUCT.md \
scripts/benchmark_memory_usage.sh \
- scripts/Dockerfile \
scripts/plot_memory_usage.gp \
scripts/benchmarks/README \
todo \
@@ -608,7 +608,7 @@ EXTRA_DIST = \
src/modules/bluetooth/meson.build \
src/modules/echo-cancel/meson.build \
src/modules/gsettings/meson.build \
- src/modules/gsettings/post-install.sh \
+ src/modules/gsettings/meson_post_install.py \
src/modules/meson.build \
src/modules/oss/meson.build \
src/modules/raop/meson.build \
diff --git a/NEWS b/NEWS
index 2d5f4b0..782a612 100644
--- a/NEWS
+++ b/NEWS
@@ -3,20 +3,32 @@ PulseAudio 13.0
Changes at a glance:
* Added support for Dolby TrueHD and DTS-HD Master Audio
+ * Improved 5.1 surround channel routing
* Improved initial card profile selection for ALSA cards
+ * Automatically switch away from unavailable card profiles
* Bluetooth card profile choices aren't persistent any more by default
- * Added support for SteelSeries Arctis 5 USB headset
+ * Added support for some SteelSeries Arctis 5 USB headsets
+ * Removed KDE specific routing configuration
+ * New information collection script for bug reports: pa-info
* New "max_latency_msec" module argument for module-loopback
+ * New "fast_adjust_threshold_msec" module argument for module-loopback
* New "stream_name" module argument for module-rtp-send
* Fixed S/PDIF for CMEDIA USB2.0 High-Speed True HD Audio
* Use source sample spec and channel map by default in module-loopback
+ * module-role-cork and module-role-ducking can now use recording streams as triggers
* New "avoid_resampling" module argument for module-udev-detect and module-alsa-card
* "avoid_resampling" also tries to avoid format conversion if the ALSA device supports it
+ * Added support for non-PCM formats in module-null-sink
+ * More efficient channel remapping in some cases for 32-bit streams
+ * Removed the "latency_time" option from module-null-source
* New function to enable realtime scheduling for client threads
+ * New convenience functions for getting parameters from pa_format_info
+ * New function for pa_threaded_mainloop to run a callback in the mainloop thread without the mainloop lock being held
+ * Const-ification of parameters across headers
* Removed BlueZ 4 support
* Dropped intltool
* Introduction of the Meson build system
- * Const-ification of parameters across headers
+ * New build option for improving build reproducibility
* Minor bug-fixes, bindings updates and several translation updates
Detailed change log:
diff --git a/build-aux/config.guess b/build-aux/config.guess
index f50dcdb..b33c9e8 100755
--- a/build-aux/config.guess
+++ b/build-aux/config.guess
@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2018-02-24'
+timestamp='2018-08-29'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -84,8 +84,6 @@ if test $# != 0; then
exit 1
fi
-trap 'exit 1' 1 2 15
-
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
@@ -96,34 +94,39 @@ trap 'exit 1' 1 2 15
# Portable tmp directory creation inspired by the Autoconf team.
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > "$dummy.c" ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 1 2 13 15
+trap 'exitcode=$?; test -z "$tmp" || rm -fr "$tmp"; exit $exitcode' 0
+
+set_cc_for_build() {
+ : "${TMPDIR=/tmp}"
+ # shellcheck disable=SC2039
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+ dummy=$tmp/dummy
+ case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+ ,,) echo "int x;" > "$dummy.c"
+ for driver in cc gcc c89 c99 ; do
+ if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$driver"
+ break
+ fi
+ done
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+ esac
+}
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH
fi
@@ -138,7 +141,7 @@ Linux|GNU|GNU/*)
# We could probably try harder.
LIBC=gnu
- eval "$set_cc_for_build"
+ set_cc_for_build
cat <<-EOF > "$dummy.c"
#include <features.h>
#if defined(__UCLIBC__)
@@ -199,7 +202,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
os=netbsdelf
;;
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval "$set_cc_for_build"
+ set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
then
@@ -237,7 +240,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "$machine-${os}${release}${abi}"
+ echo "$machine-${os}${release}${abi-}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -389,20 +392,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
echo i386-pc-auroraux"$UNAME_RELEASE"
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval "$set_cc_for_build"
- SUN_ARCH=i386
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH=x86_64
- fi
- fi
- echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
+ UNAME_REL="`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
+ case `isainfo -b` in
+ 32)
+ echo i386-pc-solaris2"$UNAME_REL"
+ ;;
+ 64)
+ echo x86_64-pc-solaris2"$UNAME_REL"
+ ;;
+ esac
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -482,7 +480,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
echo clipper-intergraph-clix"$UNAME_RELEASE"
exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
- eval "$set_cc_for_build"
+ set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
@@ -579,7 +577,7 @@ EOF
exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval "$set_cc_for_build"
+ set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include <sys/systemcfg.h>
@@ -660,7 +658,7 @@ EOF
esac
fi
if [ "$HP_ARCH" = "" ]; then
- eval "$set_cc_for_build"
+ set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#define _HPUX_SOURCE
@@ -700,7 +698,7 @@ EOF
esac
if [ "$HP_ARCH" = hppa2.0w ]
then
- eval "$set_cc_for_build"
+ set_cc_for_build
# hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
# 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
@@ -726,7 +724,7 @@ EOF
echo ia64-hp-hpux"$HPUX_REV"
exit ;;
3050*:HI-UX:*:*)
- eval "$set_cc_for_build"
+ set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#include <unistd.h>
int
@@ -840,6 +838,17 @@ EOF
*:BSD/OS:*:*)
echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
exit ;;
+ arm:FreeBSD:*:*)
+ UNAME_PROCESSOR=`uname -p`
+ set_cc_for_build
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi
+ else
+ echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf
+ fi
+ exit ;;
*:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p`
case "$UNAME_PROCESSOR" in
@@ -894,8 +903,8 @@ EOF
# other systems with GNU libc and userland
echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
exit ;;
- i*86:Minix:*:*)
- echo "$UNAME_MACHINE"-pc-minix
+ *:Minix:*:*)
+ echo "$UNAME_MACHINE"-unknown-minix
exit ;;
aarch64:Linux:*:*)
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -922,7 +931,7 @@ EOF
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
arm*:Linux:*:*)
- eval "$set_cc_for_build"
+ set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
@@ -971,7 +980,7 @@ EOF
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
- eval "$set_cc_for_build"
+ set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
#undef CPU
#undef ${UNAME_MACHINE}
@@ -1046,11 +1055,7 @@ EOF
echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
exit ;;
x86_64:Linux:*:*)
- if objdump -f /bin/sh | grep -q elf32-x86-64; then
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32
- else
- echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
- fi
+ echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
exit ;;
xtensa*:Linux:*:*)
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
@@ -1289,7 +1294,7 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- eval "$set_cc_for_build"
+ set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
@@ -1362,6 +1367,7 @@ EOF
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
+ # shellcheck disable=SC2154
if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
@@ -1473,7 +1479,7 @@ EOF
exit 1
# Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/build-aux/config.sub b/build-aux/config.sub
index 1d8e98b..b51fb8c 100755
--- a/build-aux/config.sub
+++ b/build-aux/config.sub
@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2018 Free Software Foundation, Inc.
-timestamp='2018-02-22'
+timestamp='2018-08-29'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -110,1223 +110,1159 @@ case $# in
exit 1;;
esac
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
- linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
- kopensolaris*-gnu* | cloudabi*-eabi* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- android-linux)
- os=-linux-android
- basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
- ;;
- *)
- basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
- if [ "$basic_machine" != "$1" ]
- then os=`echo "$1" | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
+# Split fields of configuration type
+IFS="-" read -r field1 field2 field3 field4 <<EOF
+$1
+EOF
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze*)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*178)
- os=-lynxos178
- ;;
- -lynx*5)
- os=-lynxos5
+# Separate into logical components for further validation
+case $1 in
+ *-*-*-*-*)
+ echo Invalid configuration \`"$1"\': more than four components >&2
+ exit 1
;;
- -lynx*)
- os=-lynxos
+ *-*-*-*)
+ basic_machine=$field1-$field2
+ os=$field3-$field4
;;
- -ptx*)
- basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
+ *-*-*)
+ # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+ # parts
+ maybe_os=$field2-$field3
+ case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc \
+ | linux-newlib* | linux-musl* | linux-uclibc* | uclinux-uclibc* \
+ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+ | storm-chaos* | os2-emx* | rtmk-nova*)
+ basic_machine=$field1
+ os=$maybe_os
+ ;;
+ android-linux)
+ basic_machine=$field1-unknown
+ os=linux-android
+ ;;
+ *)
+ basic_machine=$field1-$field2
+ os=$field3
+ ;;
+ esac
;;
- -psos*)
- os=-psos
+ *-*)
+ # A lone config we happen to match not fitting any patern
+ case $field1-$field2 in
+ decstation-3100)
+ basic_machine=mips-dec
+ os=
+ ;;
+ *-*)
+ # Second component is usually, but not always the OS
+ case $field2 in
+ # Prevent following clause from handling this valid os
+ sun*os*)
+ basic_machine=$field1
+ os=$field2
+ ;;
+ # Manufacturers
+ dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+ | unicom* | ibm* | next | hp | isi* | apollo | altos* \
+ | convergent* | ncr* | news | 32* | 3600* | 3100* \
+ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+ | ultra | tti* | harris | dolphin | highlevel | gould \
+ | cbm | ns | masscomp | apple | axis | knuth | cray \
+ | microblaze* | sim | cisco \
+ | oki | wec | wrs | winbond)
+ basic_machine=$field1-$field2
+ os=
+ ;;
+ *)
+ basic_machine=$field1
+ os=$field2
+ ;;
+ esac
+ ;;
+ esac
;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
+ *)
+ # Convert single-component short-hands not valid as part of
+ # multi-component configurations.
+ case $field1 in
+ 386bsd)
+ basic_machine=i386-pc
+ os=bsd
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=scout
+ ;;
+ alliant)
+ basic_machine=fx80-alliant
+ os=
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ os=
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=sysv
+ ;;
+ amiga)
+ basic_machine=m68k-unknown
+ os=
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=linux
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=bsd
+ ;;
+ cray)
+ basic_machine=j90-cray
+ os=unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ os=
+ ;;
+ da30)
+ basic_machine=m68k-da30
+ os=
+ ;;
+ decstation | pmax | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ os=
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=msdosdjgpp
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=ebmon
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=ose
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=go32
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=sysv3
+ ;;
+ hp300)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=hpux
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=proelf
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=mach
+ ;;
+ vsta)
+ basic_machine=i386-pc
+ os=vsta
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=linux
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=sysv
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=mingw32ce
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=msdos
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-pc
+ os=netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=sysv
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=nonstopux
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=os68k
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=linux
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=coff
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ os=
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=sysv2
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ os=
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ os=
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=sunos4
+ ;;
+ sun3)
+ basic_machine=m68k-sun
+ os=
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=sunos4
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ os=
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=solaris2
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ os=
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=unicos
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=tops20
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=vms
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=vxworks
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=mingw32
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=unicos
+ ;;
+ *)
+ basic_machine=$1
+ os=
+ ;;
+ esac
;;
esac
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | aarch64 | aarch64_be \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arceb \
- | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
- | avr | avr32 \
- | ba \
- | be32 | be64 \
- | bfin \
- | c4x | c8051 | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | e2k | epiphany \
- | fido | fr30 | frv | ft32 \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | hexagon \
- | i370 | i860 | i960 | ia16 | ia64 \
- | ip2k | iq2000 \
- | k1om \
- | le32 | le64 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa32r6 | mipsisa32r6el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64r6 | mipsisa64r6el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipsr5900 | mipsr5900el \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nds32 | nds32le | nds32be \
- | nios | nios2 | nios2eb | nios2el \
- | ns16k | ns32k \
- | open8 | or1k | or1knd | or32 \
- | pdp10 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle \
- | pru \
- | pyramid \
- | riscv32 | riscv64 \
- | rl78 | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu \
- | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
- | visium \
- | wasm32 \
- | x86 | xc16x | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- c54x)
- basic_machine=tic54x-unknown
- ;;
- c55x)
- basic_machine=tic55x-unknown
- ;;
- c6x)
- basic_machine=tic6x-unknown
- ;;
- leon|leon[3-9])
- basic_machine=sparc-$basic_machine
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
- basic_machine=$basic_machine-unknown
- os=-none
+ # Here we handle the default manufacturer of certain CPU types. It is in
+ # some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ cpu=hppa1.1
+ vendor=winbond
;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
+ op50n)
+ cpu=hppa1.1
+ vendor=oki
;;
- ms1)
- basic_machine=mt-unknown
+ op60c)
+ cpu=hppa1.1
+ vendor=oki
;;
-
- strongarm | thumb | xscale)
- basic_machine=arm-unknown
+ ibm*)
+ cpu=i370
+ vendor=ibm
;;
- xgate)
- basic_machine=$basic_machine-unknown
- os=-none
+ orion105)
+ cpu=clipper
+ vendor=highlevel
;;
- xscaleeb)
- basic_machine=armeb-unknown
+ mac | mpw | mac-mpw)
+ cpu=m68k
+ vendor=apple
;;
-
- xscaleel)
- basic_machine=armel-unknown
+ pmac | pmac-mpw)
+ cpu=powerpc
+ vendor=apple
;;
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | aarch64-* | aarch64_be-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | ba-* \
- | be32-* | be64-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* \
- | c8051-* | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | e2k-* | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | hexagon-* \
- | i*86-* | i860-* | i960-* | ia16-* | ia64-* \
- | ip2k-* | iq2000-* \
- | k1om-* \
- | le32-* | le64-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
- | microblaze-* | microblazeel-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa32r6-* | mipsisa32r6el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64r6-* | mipsisa64r6el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipsr5900-* | mipsr5900el-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nds32-* | nds32le-* | nds32be-* \
- | nios-* | nios2-* | nios2eb-* | nios2el-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | open8-* \
- | or1k*-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
- | pru-* \
- | pyramid-* \
- | riscv32-* | riscv64-* \
- | rl78-* | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
- | tahoe-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile*-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
- | vax-* \
- | visium-* \
- | wasm32-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-pc
- os=-bsd
- ;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
+ cpu=m68000
+ vendor=att
;;
3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- asmjs)
- basic_machine=asmjs-unknown
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- os=-linux
+ cpu=we32k
+ vendor=att
;;
bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c54x-*)
- basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- c55x-*)
- basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- c6x-*)
- basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16 | cr16-*)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
+ cpu=powerpc
+ vendor=ibm
+ os=cnk
;;
decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
+ cpu=pdp10
+ vendor=dec
+ os=tops10
;;
decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
+ cpu=pdp10
+ vendor=dec
+ os=tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
+ cpu=m68k
+ vendor=motorola
;;
dpx2*)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- e500v[12])
- basic_machine=powerpc-unknown
- os=$os"spe"
- ;;
- e500v[12]-*)
- basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- os=$os"spe"
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
+ cpu=m68k
+ vendor=bull
+ os=sysv3
;;
encore | umax | mmax)
- basic_machine=ns32k-encore
+ cpu=ns32k
+ vendor=encore
;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
+ elxsi)
+ cpu=elxsi
+ vendor=elxsi
+ os=${os:-bsd}
;;
fx2800)
- basic_machine=i860-alliant
+ cpu=i860
+ vendor=alliant
;;
genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
+ cpu=ns32k
+ vendor=ns
;;
h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
+ cpu=hppa1.1
+ vendor=hitachi
+ os=hiuxwe2
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
+ cpu=hppa1.0
+ vendor=hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
+ cpu=m68000
+ vendor=hp
;;
hp9k3[2-9][0-9])
- basic_machine=m68k-hp
+ cpu=m68k
+ vendor=hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
+ cpu=hppa1.0
+ vendor=hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
+ cpu=hppa1.1
+ vendor=hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
+ cpu=hppa1.0
+ vendor=hp
;;
i*86v32)
- basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
- os=-sysv32
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=sysv32
;;
i*86v4*)
- basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
- os=-sysv4
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=sysv4
;;
i*86v)
- basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
- os=-sysv
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=sysv
;;
i*86sol2)
- basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
- os=-solaris2
+ cpu=`echo "$1" | sed -e 's/86.*/86/'`
+ vendor=pc
+ os=solaris2
;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- vsta)
- basic_machine=i386-unknown
- os=-vsta
+ j90 | j90-cray)
+ cpu=j90
+ vendor=cray
+ os=${os:-unicos}
;;
iris | iris4d)
- basic_machine=mips-sgi
+ cpu=mips
+ vendor=sgi
case $os in
- -irix*)
+ irix*)
;;
*)
- os=-irix4
+ os=irix4
;;
esac
;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- leon-*|leon[3-9]-*)
- basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze*)
- basic_machine=microblaze-xilinx
- ;;
- mingw64)
- basic_machine=x86_64-pc
- os=-mingw64
- ;;
- mingw32)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- moxiebox)
- basic_machine=moxie-unknown
- os=-moxiebox
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
- ;;
- msys)
- basic_machine=i686-pc
- os=-msys
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- nacl)
- basic_machine=le32-unknown
- os=-nacl
+ cpu=m68000
+ vendor=convergent
;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
+ *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ cpu=m68k
+ vendor=atari
+ os=mint
;;
news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
+ cpu=mips
+ vendor=sony
+ os=newsos
;;
next | m*-next)
- basic_machine=m68k-next
+ cpu=m68k
+ vendor=next
case $os in
- -nextstep* )
+ nextstep* )
;;
- -ns2*)
- os=-nextstep2
+ ns2*)
+ os=nextstep2
;;
*)
- os=-nextstep3
+ os=nextstep3
;;
esac
;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
np1)
- basic_machine=np1-gould
- ;;
- neo-tandem)
- basic_machine=neo-tandem
- ;;
- nse-tandem)
- basic_machine=nse-tandem
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- nsv-tandem)
- basic_machine=nsv-tandem
- ;;
- nsx-tandem)
- basic_machine=nsx-tandem
+ cpu=np1
+ vendor=gould
;;
op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
+ cpu=hppa1.1
+ vendor=oki
+ os=proelf
;;
pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- os=-linux
+ cpu=hppa1.1
+ vendor=hitachi
+ os=hiuxwe2
;;
pbd)
- basic_machine=sparc-tti
+ cpu=sparc
+ vendor=tti
;;
pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ cpu=m68k
+ vendor=tti
;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ pc532)
+ cpu=ns32k
+ vendor=pc532
;;
pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc | ppcbe) basic_machine=powerpc-unknown
- ;;
- ppc-* | ppcbe-*)
- basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ cpu=pn
+ vendor=gould
;;
- ppcle | powerpclittle)
- basic_machine=powerpcle-unknown
+ power)
+ cpu=power
+ vendor=ibm
;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
+ ps2)
+ cpu=i386
+ vendor=ibm
;;
- ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ rm[46]00)
+ cpu=mips
+ vendor=siemens
;;
- ppc64le | powerpc64little)
- basic_machine=powerpc64le-unknown
+ rtpc | rtpc-*)
+ cpu=romp
+ vendor=ibm
;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ sde)
+ cpu=mipsisa32
+ vendor=sde
+ os=${os:-elf}
;;
- ps2)
- basic_machine=i386-ibm
+ simso-wrs)
+ cpu=sparclite
+ vendor=wrs
+ os=vxworks
;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
+ tower | tower-32)
+ cpu=m68k
+ vendor=ncr
;;
- rdos | rdos64)
- basic_machine=x86_64-pc
- os=-rdos
+ vpp*|vx|vx-*)
+ cpu=f301
+ vendor=fujitsu
;;
- rdos32)
- basic_machine=i386-pc
- os=-rdos
+ w65)
+ cpu=w65
+ vendor=wdc
;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
+ w89k-*)
+ cpu=hppa1.1
+ vendor=winbond
+ os=proelf
;;
- rm[46]00)
- basic_machine=mips-siemens
+ none)
+ cpu=none
+ vendor=none
;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
+ leon|leon[3-9])
+ cpu=sparc
+ vendor=$basic_machine
;;
- s390 | s390-*)
- basic_machine=s390-ibm
+ leon-*|leon[3-9]-*)
+ cpu=sparc
+ vendor=`echo "$basic_machine" | sed 's/-.*//'`
;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
+
+ *-*)
+ IFS="-" read -r cpu vendor <<EOF
+$basic_machine
+EOF
;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ cpu=$basic_machine
+ vendor=pc
;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
+ # These rules are duplicated from below for sake of the special case above;
+ # i.e. things that normalized to x86 arches should also default to "pc"
+ pc98)
+ cpu=i386
+ vendor=pc
;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
+ x64 | amd64)
+ cpu=x86_64
+ vendor=pc
;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
+ # Recognize the basic CPU types without company name.
+ *)
+ cpu=$basic_machine
+ vendor=unknown
;;
- sei)
- basic_machine=mips-sei
- os=-seiux
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+ # Here we handle the default manufacturer of certain CPU types in cannonical form. It is in
+ # some cases the only manufacturer, in others, it is the most popular.
+ craynv-unknown)
+ vendor=cray
+ os=${os:-unicosmp}
;;
- sequent)
- basic_machine=i386-sequent
+ c90-unknown | c90-cray)
+ vendor=cray
+ os=${os:-unicos}
;;
- sh5el)
- basic_machine=sh5le-unknown
+ fx80-unknown)
+ vendor=alliant
;;
- simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
+ romp-unknown)
+ vendor=ibm
;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
+ mmix-unknown)
+ vendor=knuth
;;
- spur)
- basic_machine=spur-unknown
+ microblaze-unknown | microblazeel-unknown)
+ vendor=xilinx
;;
- st2000)
- basic_machine=m68k-tandem
+ rs6000-unknown)
+ vendor=ibm
;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
+ vax-unknown)
+ vendor=dec
;;
- strongarm-* | thumb-*)
- basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+ pdp11-unknown)
+ vendor=dec
;;
- sun2)
- basic_machine=m68000-sun
+ we32k-unknown)
+ vendor=att
;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
+ cydra-unknown)
+ vendor=cydrome
;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
+ i370-ibm*)
+ vendor=ibm
;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
+ orion-unknown)
+ vendor=highlevel
;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
+ xps-unknown | xps100-unknown)
+ cpu=xps100
+ vendor=honeywell
;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
+
+ # Here we normalize CPU types with a missing or matching vendor
+ dpx20-unknown | dpx20-bull)
+ cpu=rs6000
+ vendor=bull
+ os=${os:-bosx}
;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
+
+ # Here we normalize CPU types irrespective of the vendor
+ amd64-*)
+ cpu=x86_64
;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
+ blackfin-*)
+ cpu=bfin
+ os=linux
;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
+ c54x-*)
+ cpu=tic54x
;;
- sun4)
- basic_machine=sparc-sun
+ c55x-*)
+ cpu=tic55x
;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
+ c6x-*)
+ cpu=tic6x
;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
+ e500v[12]-*)
+ cpu=powerpc
+ os=$os"spe"
;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
+ mips3*-*)
+ cpu=mips64
;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
+ ms1-*)
+ cpu=mt
;;
- t90)
- basic_machine=t90-cray
- os=-unicos
+ m68knommu-*)
+ cpu=m68k
+ os=linux
;;
- tile*)
- basic_machine=$basic_machine-unknown
- os=-linux-gnu
+ m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+ cpu=s12z
;;
- tx39)
- basic_machine=mipstx39-unknown
+ openrisc-*)
+ cpu=or32
;;
- tx39el)
- basic_machine=mipstx39el-unknown
+ parisc-*)
+ cpu=hppa
+ os=linux
;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ cpu=i586
;;
- tower | tower-32)
- basic_machine=m68k-ncr
+ pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+ cpu=i686
;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ cpu=i686
;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
+ pentium4-*)
+ cpu=i786
;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
+ pc98-*)
+ cpu=i386
;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
+ ppc-* | ppcbe-*)
+ cpu=powerpc
;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
+ ppcle-* | powerpclittle-*)
+ cpu=powerpcle
;;
- vms)
- basic_machine=vax-dec
- os=-vms
+ ppc64-*)
+ cpu=powerpc64
;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
+ ppc64le-* | powerpc64little-*)
+ cpu=powerpc64le
;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
+ sb1-*)
+ cpu=mipsisa64sb1
;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
+ sb1el-*)
+ cpu=mipsisa64sb1el
;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
+ sh5e[lb]-*)
+ cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
;;
- w65*)
- basic_machine=w65-wdc
- os=-none
+ spur-*)
+ cpu=spur
;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
+ strongarm-* | thumb-*)
+ cpu=arm
;;
- x64)
- basic_machine=x86_64-pc
+ tx39-*)
+ cpu=mipstx39
;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
+ tx39el-*)
+ cpu=mipstx39el
;;
- xps | xps100)
- basic_machine=xps100-honeywell
+ x64-*)
+ cpu=x86_64
;;
xscale-* | xscalee[bl]-*)
- basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- none)
- basic_machine=none-none
- os=-none
+ cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;;
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
+ # Recognize the cannonical CPU Types that limit and/or modify the
+ # company names they are paired with.
+ cr16-*)
+ os=${os:-elf}
;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
+ crisv32-* | etraxfs*-*)
+ cpu=crisv32
+ vendor=axis
;;
- mmix)
- basic_machine=mmix-knuth
+ cris-* | etrax*-*)
+ cpu=cris
+ vendor=axis
;;
- rs6000)
- basic_machine=rs6000-ibm
+ crx-*)
+ os=${os:-elf}
;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
+ neo-tandem)
+ cpu=neo
+ vendor=tandem
;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
+ nse-tandem)
+ cpu=nse
+ vendor=tandem
;;
- cydra)
- basic_machine=cydra-cydrome
+ nsr-tandem)
+ cpu=nsr
+ vendor=tandem
;;
- orion)
- basic_machine=orion-highlevel
+ nsv-tandem)
+ cpu=nsv
+ vendor=tandem
;;
- orion105)
- basic_machine=clipper-highlevel
+ nsx-tandem)
+ cpu=nsx
+ vendor=tandem
;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
+ s390-*)
+ cpu=s390
+ vendor=ibm
;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
+ s390x-*)
+ cpu=s390x
+ vendor=ibm
;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
+ tile*-*)
+ os=${os:-linux-gnu}
;;
+
*)
- echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
- exit 1
+ # Recognize the cannonical CPU types that are allowed with any
+ # company name.
+ case $cpu in
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | abacus \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+ | alphapca5[67] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[lb]e | arme[lb] | armv* \
+ | avr | avr32 \
+ | asmjs \
+ | ba \
+ | be32 | be64 \
+ | bfin | bs2000 \
+ | c[123]* | c30 | [cjt]90 | c4x \
+ | c8051 | clipper | craynv | csky | cydra \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | elxsi | epiphany \
+ | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+ | h8300 | h8500 \
+ | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i*86 | i860 | i960 | ia16 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle \
+ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \
+ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \
+ | m88110 | m88k | maxq | mb | mcore | mep | metag \
+ | microblaze | microblazeel \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mmix \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nfp \
+ | nios | nios2 | nios2eb | nios2el \
+ | none | np1 | ns16k | ns32k \
+ | open8 \
+ | or1k* \
+ | or32 \
+ | orion \
+ | pdp10 | pdp11 | pj | pjl | pn | power \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+ | pru \
+ | pyramid \
+ | riscv | riscv32 | riscv64 \
+ | rl78 | romp | rs6000 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+ | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+ | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+ | spu \
+ | tahoe \
+ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+ | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+ | vax \
+ | visium \
+ | wasm32 \
+ | we32k \
+ | x86 | x86_64 | xc16x | xgate | xps100 \
+ | xstormy16 | xtensa* \
+ | ymp \
+ | z8k | z80)
+ ;;
+
+ *)
+ echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+ exit 1
+ ;;
+ esac
;;
esac
# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+ digital*)
+ vendor=dec
;;
- *-commodore*)
- basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+ commodore*)
+ vendor=cbm
;;
*)
;;
@@ -1334,199 +1270,245 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
-if [ x"$os" != x"" ]
+if [ x$os != x ]
then
case $os in
# First match some system type aliases that might get confused
# with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
+ # solaris* is a basic system type, with this one exception.
+ auroraux)
+ os=auroraux
;;
- -solaris1 | -solaris1.*)
+ bluegene*)
+ os=cnk
+ ;;
+ solaris1 | solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
- -solaris)
- os=-solaris2
+ solaris)
+ os=solaris2
;;
- -unixware*)
- os=-sysv4.2uw
+ unixware*)
+ os=sysv4.2uw
;;
- -gnu/linux*)
+ gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# es1800 is here to avoid being matched by es* (a different OS)
- -es1800*)
- os=-ose
+ es1800*)
+ os=ose
+ ;;
+ # Some version numbers need modification
+ chorusos*)
+ os=chorusos
+ ;;
+ isc)
+ os=isc2.2
+ ;;
+ sco6)
+ os=sco5v6
+ ;;
+ sco5)
+ os=sco3.2v5
+ ;;
+ sco4)
+ os=sco3.2v4
+ ;;
+ sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ ;;
+ sco3.2v[4-9]* | sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ ;;
+ scout)
+ # Don't match below
+ ;;
+ sco*)
+ os=sco3.2v2
+ ;;
+ psos*)
+ os=psos
;;
# Now accept the basic system types.
# The portable systems comes first.
# Each alternative MUST end in a * to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* | -plan9* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* | -cloudabi* | -sortix* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
- | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
- | -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
- | -midnightbsd*)
+ # sysv* is not here because it comes later, after sysvr4.
+ gnu* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+ | *vms* | esix* | aix* | cnk* | sunos | sunos[34]*\
+ | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+ | sym* | kopensolaris* | plan9* \
+ | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+ | aos* | aros* | cloudabi* | sortix* \
+ | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+ | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+ | knetbsd* | mirbsd* | netbsd* \
+ | bitrig* | openbsd* | solidbsd* | libertybsd* \
+ | ekkobsd* | kfreebsd* | freebsd* | riscix* | lynxos* \
+ | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+ | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+ | udi* | eabi* | lites* | ieee* | go32* | aux* | hcos* \
+ | chorusrdb* | cegcc* | glidix* \
+ | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+ | midipix* | mingw32* | mingw64* | linux-gnu* | linux-android* \
+ | linux-newlib* | linux-musl* | linux-uclibc* \
+ | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+ | interix* | uwin* | mks* | rhapsody* | darwin* \
+ | openstep* | oskit* | conix* | pw32* | nonstopux* \
+ | storm-chaos* | tops10* | tenex* | tops20* | its* \
+ | os2* | vos* | palmos* | uclinux* | nucleus* \
+ | morphos* | superux* | rtmk* | windiss* \
+ | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+ | midnightbsd*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
+ qnx*)
+ case $cpu in
+ x86 | i*86)
;;
*)
- os=-nto$os
+ os=nto-$os
;;
esac
;;
- -nto-qnx*)
+ hiux*)
+ os=hiuxwe2
+ ;;
+ nto-qnx*)
;;
- -nto*)
+ nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
- -sim | -xray | -os68k* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ sim | xray | os68k* | v88r* \
+ | windows* | osx | abug | netware* | os9* \
+ | macos* | mpw* | magic* | mmixware* | mon960* | lnews*)
+ ;;
+ linux-dietlibc)
+ os=linux-dietlibc
+ ;;
+ linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ lynx*178)
+ os=lynxos178
;;
- -mac*)
+ lynx*5)
+ os=lynxos5
+ ;;
+ lynx*)
+ os=lynxos
+ ;;
+ mac*)
os=`echo "$os" | sed -e 's|mac|macos|'`
;;
- -linux-dietlibc)
- os=-linux-dietlibc
+ opened*)
+ os=openedition
;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ os400*)
+ os=os400
;;
- -sunos5*)
+ sunos5*)
os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
;;
- -sunos6*)
+ sunos6*)
os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
+ wince*)
+ os=wince
;;
- -wince*)
- os=-wince
+ utek*)
+ os=bsd
;;
- -utek*)
- os=-bsd
+ dynix*)
+ os=bsd
;;
- -dynix*)
- os=-bsd
+ acis*)
+ os=aos
;;
- -acis*)
- os=-aos
+ atheos*)
+ os=atheos
;;
- -atheos*)
- os=-atheos
+ syllable*)
+ os=syllable
;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
+ 386bsd)
+ os=bsd
;;
- -ctix* | -uts*)
- os=-sysv
+ ctix* | uts*)
+ os=sysv
;;
- -nova*)
- os=-rtmk-nova
+ nova*)
+ os=rtmk-nova
;;
- -ns2)
- os=-nextstep2
+ ns2)
+ os=nextstep2
;;
- -nsk*)
- os=-nsk
+ nsk*)
+ os=nsk
;;
# Preserve the version number of sinix5.
- -sinix5.*)
+ sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
- -sinix*)
- os=-sysv4
+ sinix*)
+ os=sysv4
;;
- -tpf*)
- os=-tpf
+ tpf*)
+ os=tpf
;;
- -triton*)
- os=-sysv3
+ triton*)
+ os=sysv3
;;
- -oss*)
- os=-sysv3
+ oss*)
+ os=sysv3
;;
- -svr4*)
- os=-sysv4
+ svr4*)
+ os=sysv4
;;
- -svr3)
- os=-sysv3
+ svr3)
+ os=sysv3
;;
- -sysvr4)
- os=-sysv4
+ sysvr4)
+ os=sysv4
;;
- # This must come after -sysvr4.
- -sysv*)
+ # This must come after sysvr4.
+ sysv*)
;;
- -ose*)
- os=-ose
+ ose*)
+ os=ose
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+ os=mint
;;
- -zvmoe)
- os=-zvmoe
+ zvmoe)
+ os=zvmoe
;;
- -dicos*)
- os=-dicos
+ dicos*)
+ os=dicos
;;
- -pikeos*)
+ pikeos*)
# Until real need of OS specific support for
# particular features comes up, bare metal
# configurations are quite functional.
- case $basic_machine in
+ case $cpu in
arm*)
- os=-eabi
+ os=eabi
;;
*)
- os=-elf
+ os=elf
;;
esac
;;
- -nacl*)
+ nacl*)
;;
- -ios)
+ ios)
;;
- -none)
+ none)
+ ;;
+ *-eabi)
;;
*)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
exit 1
;;
@@ -1543,258 +1525,265 @@ else
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
-case $basic_machine in
+case $cpu-$vendor in
score-*)
- os=-elf
+ os=elf
;;
spu-*)
- os=-elf
+ os=elf
;;
*-acorn)
- os=-riscix1.2
+ os=riscix1.2
;;
arm*-rebel)
- os=-linux
+ os=linux
;;
arm*-semi)
- os=-aout
+ os=aout
;;
c4x-* | tic4x-*)
- os=-coff
+ os=coff
;;
c8051-*)
- os=-elf
+ os=elf
+ ;;
+ clipper-intergraph)
+ os=clix
;;
hexagon-*)
- os=-elf
+ os=elf
;;
tic54x-*)
- os=-coff
+ os=coff
;;
tic55x-*)
- os=-coff
+ os=coff
;;
tic6x-*)
- os=-coff
+ os=coff
;;
# This must come before the *-dec entry.
pdp10-*)
- os=-tops20
+ os=tops20
;;
pdp11-*)
- os=-none
+ os=none
;;
*-dec | vax-*)
- os=-ultrix4.2
+ os=ultrix4.2
;;
m68*-apollo)
- os=-domain
+ os=domain
;;
i386-sun)
- os=-sunos4.0.2
+ os=sunos4.0.2
;;
m68000-sun)
- os=-sunos3
+ os=sunos3
;;
m68*-cisco)
- os=-aout
+ os=aout
;;
mep-*)
- os=-elf
+ os=elf
;;
mips*-cisco)
- os=-elf
+ os=elf
;;
mips*-*)
- os=-elf
+ os=elf
;;
or32-*)
- os=-coff
+ os=coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
+ os=sysv3
;;
sparc-* | *-sun)
- os=-sunos4.1.1
+ os=sunos4.1.1
;;
pru-*)
- os=-elf
+ os=elf
;;
*-be)
- os=-beos
+ os=beos
;;
*-ibm)
- os=-aix
+ os=aix
;;
*-knuth)
- os=-mmixware
+ os=mmixware
;;
*-wec)
- os=-proelf
+ os=proelf
;;
*-winbond)
- os=-proelf
+ os=proelf
;;
*-oki)
- os=-proelf
+ os=proelf
;;
*-hp)
- os=-hpux
+ os=hpux
;;
*-hitachi)
- os=-hiux
+ os=hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
+ os=sysv
;;
*-cbm)
- os=-amigaos
+ os=amigaos
;;
*-dg)
- os=-dgux
+ os=dgux
;;
*-dolphin)
- os=-sysv3
+ os=sysv3
;;
m68k-ccur)
- os=-rtu
+ os=rtu
;;
m88k-omron*)
- os=-luna
+ os=luna
;;
*-next)
- os=-nextstep
+ os=nextstep
;;
*-sequent)
- os=-ptx
+ os=ptx
;;
*-crds)
- os=-unos
+ os=unos
;;
*-ns)
- os=-genix
+ os=genix
;;
i370-*)
- os=-mvs
+ os=mvs
;;
*-gould)
- os=-sysv
+ os=sysv
;;
*-highlevel)
- os=-bsd
+ os=bsd
;;
*-encore)
- os=-bsd
+ os=bsd
;;
*-sgi)
- os=-irix
+ os=irix
;;
*-siemens)
- os=-sysv4
+ os=sysv4
;;
*-masscomp)
- os=-rtu
+ os=rtu
;;
f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
+ os=uxpv
;;
*-rom68k)
- os=-coff
+ os=coff
;;
*-*bug)
- os=-coff
+ os=coff
;;
*-apple)
- os=-macos
+ os=macos
;;
*-atari*)
- os=-mint
+ os=mint
+ ;;
+ *-wrs)
+ os=vxworks
;;
*)
- os=-none
+ os=none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
+case $vendor in
+ unknown)
case $os in
- -riscix*)
+ riscix*)
vendor=acorn
;;
- -sunos*)
+ sunos*)
vendor=sun
;;
- -cnk*|-aix*)
+ cnk*|-aix*)
vendor=ibm
;;
- -beos*)
+ beos*)
vendor=be
;;
- -hpux*)
+ hpux*)
vendor=hp
;;
- -mpeix*)
+ mpeix*)
vendor=hp
;;
- -hiux*)
+ hiux*)
vendor=hitachi
;;
- -unos*)
+ unos*)
vendor=crds
;;
- -dgux*)
+ dgux*)
vendor=dg
;;
- -luna*)
+ luna*)
vendor=omron
;;
- -genix*)
+ genix*)
vendor=ns
;;
- -mvs* | -opened*)
+ clix*)
+ vendor=intergraph
+ ;;
+ mvs* | opened*)
vendor=ibm
;;
- -os400*)
+ os400*)
vendor=ibm
;;
- -ptx*)
+ ptx*)
vendor=sequent
;;
- -tpf*)
+ tpf*)
vendor=ibm
;;
- -vxsim* | -vxworks* | -windiss*)
+ vxsim* | vxworks* | windiss*)
vendor=wrs
;;
- -aux*)
+ aux*)
vendor=apple
;;
- -hms*)
+ hms*)
vendor=hitachi
;;
- -mpw* | -macos*)
+ mpw* | macos*)
vendor=apple
;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ *mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
vendor=atari
;;
- -vos*)
+ vos*)
vendor=stratus
;;
esac
- basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
;;
esac
-echo "$basic_machine$os"
+echo "$cpu-$vendor-$os"
exit
# Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh
index c12c197..7f3523d 100644
--- a/build-aux/ltmain.sh
+++ b/build-aux/ltmain.sh
@@ -31,7 +31,7 @@
PROGRAM=libtool
PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-9"
+VERSION=2.4.6
package_revision=2.4.6
@@ -1370,7 +1370,7 @@ func_lt_ver ()
#! /bin/sh
# Set a version string for this script.
-scriptversion=2015-10-07.11; # UTC
+scriptversion=2014-01-07.03; # UTC
# A portable, pluggable option parser for Bourne shell.
# Written by Gary V. Vaughan, 2010
@@ -1530,8 +1530,6 @@ func_run_hooks ()
{
$debug_cmd
- _G_rc_run_hooks=false
-
case " $hookable_fns " in
*" $1 "*) ;;
*) func_fatal_error "'$1' does not support hook funcions.n" ;;
@@ -1540,16 +1538,16 @@ func_run_hooks ()
eval _G_hook_fns=\$$1_hooks; shift
for _G_hook in $_G_hook_fns; do
- if eval $_G_hook '"$@"'; then
- # store returned options list back into positional
- # parameters for next 'cmd' execution.
- eval _G_hook_result=\$${_G_hook}_result
- eval set dummy "$_G_hook_result"; shift
- _G_rc_run_hooks=:
- fi
+ eval $_G_hook '"$@"'
+
+ # store returned options list back into positional
+ # parameters for next 'cmd' execution.
+ eval _G_hook_result=\$${_G_hook}_result
+ eval set dummy "$_G_hook_result"; shift
done
- $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result
+ func_quote_for_eval ${1+"$@"}
+ func_run_hooks_result=$func_quote_for_eval_result
}
@@ -1559,16 +1557,10 @@ func_run_hooks ()
## --------------- ##
# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, you may remove/edit
-# any options that you action, and then pass back the remaining unprocessed
+# full positional parameter list in your hook function, remove any
+# options that you action, and then pass back the remaining unprocessed
# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'. In this case you also must return $EXIT_SUCCESS to let the
-# hook's caller know that it should pay attention to
-# '<hooked_function_name>_result'. Returning $EXIT_FAILURE signalizes that
-# arguments are left untouched by the hook and therefore caller will ignore the
-# result variable.
-#
-# Like this:
+# 'eval'. Like this:
#
# my_options_prep ()
# {
@@ -1578,11 +1570,9 @@ func_run_hooks ()
# usage_message=$usage_message'
# -s, --silent don'\''t print informational messages
# '
-# # No change in '$@' (ignored completely by this hook). There is
-# # no need to do the equivalent (but slower) action:
-# # func_quote_for_eval ${1+"$@"}
-# # my_options_prep_result=$func_quote_for_eval_result
-# false
+#
+# func_quote_for_eval ${1+"$@"}
+# my_options_prep_result=$func_quote_for_eval_result
# }
# func_add_hook func_options_prep my_options_prep
#
@@ -1591,37 +1581,25 @@ func_run_hooks ()
# {
# $debug_cmd
#
-# args_changed=false
-#
# # Note that for efficiency, we parse as many options as we can
# # recognise in a loop before passing the remainder back to the
# # caller on the first unrecognised argument we encounter.
# while test $# -gt 0; do
# opt=$1; shift
# case $opt in
-# --silent|-s) opt_silent=:
-# args_changed=:
-# ;;
+# --silent|-s) opt_silent=: ;;
# # Separate non-argument short options:
# -s*) func_split_short_opt "$_G_opt"
# set dummy "$func_split_short_opt_name" \
# "-$func_split_short_opt_arg" ${1+"$@"}
# shift
-# args_changed=:
# ;;
-# *) # Make sure the first unrecognised option "$_G_opt"
-# # is added back to "$@", we could need that later
-# # if $args_changed is true.
-# set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
+# *) set dummy "$_G_opt" "$*"; shift; break ;;
# esac
# done
#
-# if $args_changed; then
-# func_quote_for_eval ${1+"$@"}
-# my_silent_option_result=$func_quote_for_eval_result
-# fi
-#
-# $args_changed
+# func_quote_for_eval ${1+"$@"}
+# my_silent_option_result=$func_quote_for_eval_result
# }
# func_add_hook func_parse_options my_silent_option
#
@@ -1633,32 +1611,16 @@ func_run_hooks ()
# $opt_silent && $opt_verbose && func_fatal_help "\
# '--silent' and '--verbose' options are mutually exclusive."
#
-# false
+# func_quote_for_eval ${1+"$@"}
+# my_option_validation_result=$func_quote_for_eval_result
# }
# func_add_hook func_validate_options my_option_validation
#
-# You'll also need to manually amend $usage_message to reflect the extra
+# You'll alse need to manually amend $usage_message to reflect the extra
# options you parse. It's preferable to append if you can, so that
# multiple option parsing hooks can be added safely.
-# func_options_finish [ARG]...
-# ----------------------------
-# Finishing the option parse loop (call 'func_options' hooks ATM).
-func_options_finish ()
-{
- $debug_cmd
-
- _G_func_options_finish_exit=false
- if func_run_hooks func_options ${1+"$@"}; then
- func_options_finish_result=$func_run_hooks_result
- _G_func_options_finish_exit=:
- fi
-
- $_G_func_options_finish_exit
-}
-
-
# func_options [ARG]...
# ---------------------
# All the functions called inside func_options are hookable. See the
@@ -1668,28 +1630,17 @@ func_options ()
{
$debug_cmd
- _G_rc_options=false
-
- for my_func in options_prep parse_options validate_options options_finish
- do
- if eval func_$my_func '${1+"$@"}'; then
- eval _G_res_var='$'"func_${my_func}_result"
- eval set dummy "$_G_res_var" ; shift
- _G_rc_options=:
- fi
- done
+ func_options_prep ${1+"$@"}
+ eval func_parse_options \
+ ${func_options_prep_result+"$func_options_prep_result"}
+ eval func_validate_options \
+ ${func_parse_options_result+"$func_parse_options_result"}
- # Save modified positional parameters for caller. As a top-level
- # options-parser function we always need to set the 'func_options_result'
- # variable (regardless the $_G_rc_options value).
- if $_G_rc_options; then
- func_options_result=$_G_res_var
- else
- func_quote_for_eval ${1+"$@"}
- func_options_result=$func_quote_for_eval_result
- fi
+ eval func_run_hooks func_options \
+ ${func_validate_options_result+"$func_validate_options_result"}
- $_G_rc_options
+ # save modified positional parameters for caller
+ func_options_result=$func_run_hooks_result
}
@@ -1698,9 +1649,9 @@ func_options ()
# All initialisations required before starting the option parse loop.
# Note that when calling hook functions, we pass through the list of
# positional parameters. If a hook function modifies that list, and
-# needs to propagate that back to rest of this script, then the complete
+# needs to propogate that back to rest of this script, then the complete
# modified list must be put in 'func_run_hooks_result' before
-# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned).
+# returning.
func_hookable func_options_prep
func_options_prep ()
{
@@ -1710,14 +1661,10 @@ func_options_prep ()
opt_verbose=false
opt_warning_types=
- _G_rc_options_prep=false
- if func_run_hooks func_options_prep ${1+"$@"}; then
- _G_rc_options_prep=:
- # save modified positional parameters for caller
- func_options_prep_result=$func_run_hooks_result
- fi
+ func_run_hooks func_options_prep ${1+"$@"}
- $_G_rc_options_prep
+ # save modified positional parameters for caller
+ func_options_prep_result=$func_run_hooks_result
}
@@ -1731,20 +1678,18 @@ func_parse_options ()
func_parse_options_result=
- _G_rc_parse_options=false
# this just eases exit handling
while test $# -gt 0; do
# Defer to hook functions for initial option parsing, so they
# get priority in the event of reusing an option name.
- if func_run_hooks func_parse_options ${1+"$@"}; then
- eval set dummy "$func_run_hooks_result"; shift
- _G_rc_parse_options=:
- fi
+ func_run_hooks func_parse_options ${1+"$@"}
+
+ # Adjust func_parse_options positional parameters to match
+ eval set dummy "$func_run_hooks_result"; shift
# Break out of the loop if we already parsed every option.
test $# -gt 0 || break
- _G_match_parse_options=:
_G_opt=$1
shift
case $_G_opt in
@@ -1759,10 +1704,7 @@ func_parse_options ()
;;
--warnings|--warning|-W)
- if test $# = 0 && func_missing_arg $_G_opt; then
- _G_rc_parse_options=:
- break
- fi
+ test $# = 0 && func_missing_arg $_G_opt && break
case " $warning_categories $1" in
*" $1 "*)
# trailing space prevents matching last $1 above
@@ -1815,25 +1757,15 @@ func_parse_options ()
shift
;;
- --) _G_rc_parse_options=: ; break ;;
+ --) break ;;
-*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
- *) set dummy "$_G_opt" ${1+"$@"}; shift
- _G_match_parse_options=false
- break
- ;;
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
esac
-
- $_G_match_parse_options && _G_rc_parse_options=:
done
-
- if $_G_rc_parse_options; then
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- func_parse_options_result=$func_quote_for_eval_result
- fi
-
- $_G_rc_parse_options
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ func_parse_options_result=$func_quote_for_eval_result
}
@@ -1846,21 +1778,16 @@ func_validate_options ()
{
$debug_cmd
- _G_rc_validate_options=false
-
# Display all warnings if -W was not given.
test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
- if func_run_hooks func_validate_options ${1+"$@"}; then
- # save modified positional parameters for caller
- func_validate_options_result=$func_run_hooks_result
- _G_rc_validate_options=:
- fi
+ func_run_hooks func_validate_options ${1+"$@"}
# Bail if the options were screwed!
$exit_cmd $EXIT_FAILURE
- $_G_rc_validate_options
+ # save modified positional parameters for caller
+ func_validate_options_result=$func_run_hooks_result
}
@@ -2141,12 +2068,12 @@ include the following information:
compiler: $LTCC
compiler flags: $LTCFLAGS
linker: $LD (gnu? $with_gnu_ld)
- version: $progname $scriptversion Debian-2.4.6-9
+ version: $progname (GNU libtool) 2.4.6
automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q`
Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
+GNU libtool home page: <http://www.gnu.org/software/libtool/>.
General help using GNU software: <http://www.gnu.org/gethelp/>."
exit 0
}
@@ -2197,7 +2124,7 @@ fi
# a configuration failure hint, and exit.
func_fatal_configuration ()
{
- func__fatal_error ${1+"$@"} \
+ func_fatal_error ${1+"$@"} \
"See the $PACKAGE documentation for more information." \
"Fatal configuration error."
}
@@ -2343,8 +2270,6 @@ libtool_options_prep ()
nonopt=
preserve_args=
- _G_rc_lt_options_prep=:
-
# Shorthand for --mode=foo, only valid as the first argument
case $1 in
clean|clea|cle|cl)
@@ -2368,18 +2293,11 @@ libtool_options_prep ()
uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
shift; set dummy --mode uninstall ${1+"$@"}; shift
;;
- *)
- _G_rc_lt_options_prep=false
- ;;
esac
- if $_G_rc_lt_options_prep; then
- # Pass back the list of options.
- func_quote_for_eval ${1+"$@"}
- libtool_options_prep_result=$func_quote_for_eval_result
- fi
-
- $_G_rc_lt_options_prep
+ # Pass back the list of options.
+ func_quote_for_eval ${1+"$@"}
+ libtool_options_prep_result=$func_quote_for_eval_result
}
func_add_hook func_options_prep libtool_options_prep
@@ -2391,12 +2309,9 @@ libtool_parse_options ()
{
$debug_cmd
- _G_rc_lt_parse_options=false
-
# Perform our own loop to consume as many options as possible in
# each iteration.
while test $# -gt 0; do
- _G_match_lt_parse_options=:
_G_opt=$1
shift
case $_G_opt in
@@ -2471,22 +2386,15 @@ libtool_parse_options ()
func_append preserve_args " $_G_opt"
;;
- # An option not handled by this hook function:
- *) set dummy "$_G_opt" ${1+"$@"} ; shift
- _G_match_lt_parse_options=false
- break
- ;;
+ # An option not handled by this hook function:
+ *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
esac
- $_G_match_lt_parse_options && _G_rc_lt_parse_options=:
done
- if $_G_rc_lt_parse_options; then
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- libtool_parse_options_result=$func_quote_for_eval_result
- fi
- $_G_rc_lt_parse_options
+ # save modified positional parameters for caller
+ func_quote_for_eval ${1+"$@"}
+ libtool_parse_options_result=$func_quote_for_eval_result
}
func_add_hook func_parse_options libtool_parse_options
@@ -7366,12 +7274,10 @@ func_mode_link ()
# -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
# -specs=* GCC specs files
# -stdlib=* select c++ std lib with clang
- # -fsanitize=* Clang/GCC memory and address sanitizer
- # -fuse-ld=* Linker select flags for GCC
-64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
- -specs=*|-fsanitize=*|-fuse-ld=*)
+ -specs=*)
func_quote_for_eval "$arg"
arg=$func_quote_for_eval_result
func_append compile_command " $arg"
@@ -7664,10 +7570,7 @@ func_mode_link ()
case $pass in
dlopen) libs=$dlfiles ;;
dlpreopen) libs=$dlprefiles ;;
- link)
- libs="$deplibs %DEPLIBS%"
- test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
- ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
esac
fi
if test lib,dlpreopen = "$linkmode,$pass"; then
@@ -7986,19 +7889,19 @@ func_mode_link ()
# It is a libtool convenience library, so add in its objects.
func_append convenience " $ladir/$objdir/$old_library"
func_append old_convenience " $ladir/$objdir/$old_library"
- tmp_libs=
- for deplib in $dependency_libs; do
- deplibs="$deplib $deplibs"
- if $opt_preserve_dup_deps; then
- case "$tmp_libs " in
- *" $deplib "*) func_append specialdeplibs " $deplib" ;;
- esac
- fi
- func_append tmp_libs " $deplib"
- done
elif test prog != "$linkmode" && test lib != "$linkmode"; then
func_fatal_error "'$lib' is not a convenience library"
fi
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_preserve_dup_deps; then
+ case "$tmp_libs " in
+ *" $deplib "*) func_append specialdeplibs " $deplib" ;;
+ esac
+ fi
+ func_append tmp_libs " $deplib"
+ done
continue
fi # $pass = conv
@@ -8922,9 +8825,6 @@ func_mode_link ()
revision=$number_minor
lt_irix_increment=no
;;
- *)
- func_fatal_configuration "$modename: unknown library version type '$version_type'"
- ;;
esac
;;
no)
diff --git a/config.h.in b/config.h.in
index 7c73c67..87c4007 100644
--- a/config.h.in
+++ b/config.h.in
@@ -210,6 +210,9 @@
/* Define to 1 if you have the <grp.h> header file. */
#undef HAVE_GRP_H
+/* Have GStreamer? */
+#undef HAVE_GSTREAMER
+
/* Have GTK? */
#undef HAVE_GTK
diff --git a/configure b/configure
index 04f9ee0..b55c5e4 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pulseaudio 13.0.
+# Generated by GNU Autoconf 2.69 for pulseaudio 13.99.1.
#
# Report bugs to <pulseaudio-discuss (at) lists (dot) freedesktop (dot) org>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='pulseaudio'
PACKAGE_TARNAME='pulseaudio'
-PACKAGE_VERSION='13.0'
-PACKAGE_STRING='pulseaudio 13.0'
+PACKAGE_VERSION='13.99.1'
+PACKAGE_STRING='pulseaudio 13.99.1'
PACKAGE_BUGREPORT='pulseaudio-discuss (at) lists (dot) freedesktop (dot) org'
PACKAGE_URL='http://pulseaudio.org/'
@@ -678,6 +678,10 @@ PA_SYSTEM_GROUP
PA_SYSTEM_USER
BUILD_MANPAGES_FALSE
BUILD_MANPAGES_TRUE
+HAVE_GSTREAMER_FALSE
+HAVE_GSTREAMER_TRUE
+GSTREAMER_LIBS
+GSTREAMER_CFLAGS
HAVE_SYSTEMD_JOURNAL_FALSE
HAVE_SYSTEMD_JOURNAL_TRUE
HAVE_SYSTEMD_JOURNAL
@@ -1013,7 +1017,6 @@ infodir
docdir
oldincludedir
includedir
-runstatedir
localstatedir
sharedstatedir
sysconfdir
@@ -1098,6 +1101,7 @@ enable_systemd_daemon
enable_systemd_login
enable_systemd_journal
with_systemduserunitdir
+enable_gstreamer
enable_manpages
with_system_user
with_system_group
@@ -1188,6 +1192,8 @@ SYSTEMDLOGIN_CFLAGS
SYSTEMDLOGIN_LIBS
SYSTEMDJOURNAL_CFLAGS
SYSTEMDJOURNAL_LIBS
+GSTREAMER_CFLAGS
+GSTREAMER_LIBS
WEBRTC_CFLAGS
WEBRTC_LIBS'
@@ -1228,7 +1234,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1481,15 +1486,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
- -runstatedir | --runstatedir | --runstatedi | --runstated \
- | --runstate | --runstat | --runsta | --runst | --runs \
- | --run | --ru | --r)
- ac_prev=runstatedir ;;
- -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
- | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
- | --run=* | --ru=* | --r=*)
- runstatedir=$ac_optarg ;;
-
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1627,7 +1623,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir runstatedir
+ libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@@ -1740,7 +1736,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures pulseaudio 13.0 to adapt to many kinds of systems.
+\`configure' configures pulseaudio 13.99.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1780,7 +1776,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1811,7 +1806,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of pulseaudio 13.0:";;
+ short | recursive ) echo "Configuration of pulseaudio 13.99.1:";;
esac
cat <<\_ACEOF
@@ -1888,6 +1883,7 @@ Optional Features:
--disable-systemd-login Disable optional systemd login support
--disable-systemd-journal
Disable optional systemd journal support
+ --disable-gstreamer Disable optional GStreamer-based RTP support
--disable-manpages Disable building and installation of man pages
--disable-per-user-esound-socket
Use global esound socket directory /tmp/.esd/socket.
@@ -2058,6 +2054,10 @@ Some influential environment variables:
C compiler flags for SYSTEMDJOURNAL, overriding pkg-config
SYSTEMDJOURNAL_LIBS
linker flags for SYSTEMDJOURNAL, overriding pkg-config
+ GSTREAMER_CFLAGS
+ C compiler flags for GSTREAMER, overriding pkg-config
+ GSTREAMER_LIBS
+ linker flags for GSTREAMER, overriding pkg-config
WEBRTC_CFLAGS
C compiler flags for WEBRTC, overriding pkg-config
WEBRTC_LIBS linker flags for WEBRTC, overriding pkg-config
@@ -2129,7 +2129,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-pulseaudio configure 13.0
+pulseaudio configure 13.99.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2902,7 +2902,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by pulseaudio $as_me 13.0, which was
+It was created by pulseaudio $as_me 13.99.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3859,7 +3859,7 @@ fi
# Define the identity of the package.
PACKAGE='pulseaudio'
- VERSION='13.0'
+ VERSION='13.99.1'
cat >>confdefs.h <<_ACEOF
@@ -4116,7 +4116,7 @@ PA_PROTOCOL_VERSION=33
# The stable ABI for client applications, for the version info x:y:z
# always will hold x=z
-LIBPULSE_VERSION_INFO=21:1:21
+LIBPULSE_VERSION_INFO=21:2:21
# A simplified, synchronous, ABI-stable interface for client
@@ -8286,16 +8286,21 @@ else
/* end confdefs.h. */
#include <libintl.h>
-$gt_revision_test_code
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
extern int _nl_msg_cat_cntr;
extern int *_nl_domain_bindings;
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings)
+#else
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
+#endif
+$gt_revision_test_code
int
main ()
{
bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
;
return 0;
@@ -8415,36 +8420,42 @@ else
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
- if test "$cross_compiling" = yes; then :
-
- case "$host_os" in
- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
- *) am_cv_func_iconv_works="guessing yes" ;;
- esac
-
+ am_cv_func_iconv_works=no
+ for ac_iconv_const in '' 'const'; do
+ if test "$cross_compiling" = yes; then :
+ case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <iconv.h>
#include <string.h>
-int main ()
+
+#ifndef ICONV_CONST
+# define ICONV_CONST $ac_iconv_const
+#endif
+
+int
+main ()
{
- int result = 0;
+int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\342\202\254"; /* EURO SIGN */
+ static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
@@ -8457,14 +8468,14 @@ int main ()
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\263";
+ static ICONV_CONST char input[] = "\263";
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
@@ -8476,14 +8487,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304";
+ static ICONV_CONST char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
@@ -8496,14 +8507,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
@@ -8523,17 +8534,20 @@ int main ()
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
+
+ ;
+ return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
am_cv_func_iconv_works=yes
-else
- am_cv_func_iconv_works=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+ test "$am_cv_func_iconv_works" = no || break
+ done
LIBS="$am_save_LIBS"
fi
@@ -9039,20 +9053,25 @@ else
/* end confdefs.h. */
#include <libintl.h>
-$gt_revision_test_code
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
extern int _nl_msg_cat_cntr;
extern
#ifdef __cplusplus
"C"
#endif
const char *_nl_expand_alias (const char *);
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (""))
+#else
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
+#endif
+$gt_revision_test_code
int
main ()
{
bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
;
return 0;
@@ -9071,20 +9090,25 @@ rm -f core conftest.err conftest.$ac_objext \
/* end confdefs.h. */
#include <libintl.h>
-$gt_revision_test_code
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
extern int _nl_msg_cat_cntr;
extern
#ifdef __cplusplus
"C"
#endif
const char *_nl_expand_alias (const char *);
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (""))
+#else
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
+#endif
+$gt_revision_test_code
int
main ()
{
bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
;
return 0;
@@ -11076,7 +11100,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
-netbsd* | netbsdelf*-gnu)
+netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else
@@ -11936,8 +11960,11 @@ _LT_EOF
test $ac_status = 0; }; then
# Now try to grab the symbols.
nlist=conftest.nm
- $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5
- if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -14801,9 +14828,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
openbsd* | bitrig*)
with_gnu_ld=no
;;
- linux* | k*bsd*-gnu | gnu*)
- link_all_deplibs=no
- ;;
esac
ld_shlibs=yes
@@ -15058,7 +15082,7 @@ _LT_EOF
fi
;;
- netbsd* | netbsdelf*-gnu)
+ netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -15728,7 +15752,6 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
if test yes = "$lt_cv_irix_exported_symbol"; then
archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
- link_all_deplibs=no
else
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -15750,7 +15773,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
esac
;;
- netbsd* | netbsdelf*-gnu)
+ netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -16845,6 +16868,9 @@ fi
# before this can be enabled.
hardcode_into_libs=yes
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
# Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command
@@ -16853,7 +16879,7 @@ fi
# appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -16865,18 +16891,6 @@ fi
dynamic_linker='GNU/Linux ld.so'
;;
-netbsdelf*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='NetBSD ld.elf_so'
- ;;
-
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -18267,7 +18281,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
GXX=no
@@ -18759,7 +18773,7 @@ fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -18824,7 +18838,7 @@ fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -19163,7 +19177,7 @@ fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# FIXME: insert proper C++ library support
@@ -19247,7 +19261,7 @@ fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
@@ -19258,7 +19272,7 @@ fi
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir'
@@ -19771,7 +19785,7 @@ lt_prog_compiler_static_CXX=
;;
esac
;;
- netbsd* | netbsdelf*-gnu)
+ netbsd*)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -20146,9 +20160,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
;;
esac
;;
- linux* | k*bsd*-gnu | gnu*)
- link_all_deplibs_CXX=no
- ;;
*)
export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;;
@@ -20822,6 +20833,9 @@ fi
# before this can be enabled.
hardcode_into_libs=yes
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
# Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command
@@ -20830,7 +20844,7 @@ fi
# appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -20842,18 +20856,6 @@ fi
dynamic_linker='GNU/Linux ld.so'
;;
-netbsdelf*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='NetBSD ld.elf_so'
- ;;
-
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -23747,7 +23749,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -23793,7 +23795,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -23817,7 +23819,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -23862,7 +23864,7 @@ else
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -23886,7 +23888,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
@@ -24096,36 +24098,42 @@ else
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
- if test "$cross_compiling" = yes; then :
-
- case "$host_os" in
- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
- *) am_cv_func_iconv_works="guessing yes" ;;
- esac
-
+ am_cv_func_iconv_works=no
+ for ac_iconv_const in '' 'const'; do
+ if test "$cross_compiling" = yes; then :
+ case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <iconv.h>
#include <string.h>
-int main ()
+
+#ifndef ICONV_CONST
+# define ICONV_CONST $ac_iconv_const
+#endif
+
+int
+main ()
{
- int result = 0;
+int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\342\202\254"; /* EURO SIGN */
+ static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
@@ -24138,14 +24146,14 @@ int main ()
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\263";
+ static ICONV_CONST char input[] = "\263";
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
@@ -24157,14 +24165,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304";
+ static ICONV_CONST char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
@@ -24177,14 +24185,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
@@ -24204,17 +24212,20 @@ int main ()
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
+
+ ;
+ return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
am_cv_func_iconv_works=yes
-else
- am_cv_func_iconv_works=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+ test "$am_cv_func_iconv_works" = no || break
+ done
LIBS="$am_save_LIBS"
fi
@@ -28226,6 +28237,108 @@ $as_echo "#define HAVE_SYSTEMD_JOURNAL 1" >>confdefs.h
fi
+#### GStreamer-based RTP support (optional) ####
+
+# Check whether --enable-gstreamer was given.
+if test "${enable_gstreamer+set}" = set; then :
+ enableval=$enable_gstreamer;
+fi
+
+
+if test "x$enable_gstreamer" != "xno"; then :
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GSTREAMER" >&5
+$as_echo_n "checking for GSTREAMER... " >&6; }
+
+if test -n "$GSTREAMER_CFLAGS"; then
+ pkg_cv_GSTREAMER_CFLAGS="$GSTREAMER_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 \""; } >&5
+ ($PKG_CONFIG --exists --print-errors " gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 ") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GSTREAMER_CFLAGS=`$PKG_CONFIG --cflags " gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 " 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$GSTREAMER_LIBS"; then
+ pkg_cv_GSTREAMER_LIBS="$GSTREAMER_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 \""; } >&5
+ ($PKG_CONFIG --exists --print-errors " gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 ") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_GSTREAMER_LIBS=`$PKG_CONFIG --libs " gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 " 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ GSTREAMER_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 " 2>&1`
+ else
+ GSTREAMER_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 " 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$GSTREAMER_PKG_ERRORS" >&5
+
+ HAVE_GSTREAMER=no
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ HAVE_GSTREAMER=no
+else
+ GSTREAMER_CFLAGS=$pkg_cv_GSTREAMER_CFLAGS
+ GSTREAMER_LIBS=$pkg_cv_GSTREAMER_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ HAVE_GSTREAMER=yes
+fi
+else
+ HAVE_GSTREAMER=no
+fi
+
+if test "x$enable_gstreamer" = "xyes" && test "x$HAVE_GSTREAMER" = "xno"; then :
+ as_fn_error $? "*** GStreamer 1.0 support not found" "$LINENO" 5
+fi
+
+ if test "x$HAVE_GSTREAMER" = xyes; then
+ HAVE_GSTREAMER_TRUE=
+ HAVE_GSTREAMER_FALSE='#'
+else
+ HAVE_GSTREAMER_TRUE='#'
+ HAVE_GSTREAMER_FALSE=
+fi
+
+if test "x$HAVE_GSTREAMER" = "xyes"; then :
+
+$as_echo "#define HAVE_GSTREAMER 1" >>confdefs.h
+
+fi
+
#### Build and Install man pages ####
# Check whether --enable-manpages was given.
@@ -29648,6 +29761,10 @@ if test -z "${HAVE_SYSTEMD_JOURNAL_TRUE}" && test -z "${HAVE_SYSTEMD_JOURNAL_FAL
as_fn_error $? "conditional \"HAVE_SYSTEMD_JOURNAL\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${HAVE_GSTREAMER_TRUE}" && test -z "${HAVE_GSTREAMER_FALSE}"; then
+ as_fn_error $? "conditional \"HAVE_GSTREAMER\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${BUILD_MANPAGES_TRUE}" && test -z "${BUILD_MANPAGES_FALSE}"; then
as_fn_error $? "conditional \"BUILD_MANPAGES\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -30073,7 +30190,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by pulseaudio $as_me 13.0, which was
+This file was extended by pulseaudio $as_me 13.99.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -30140,7 +30257,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-pulseaudio config.status 13.0
+pulseaudio config.status 13.99.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
@@ -31513,6 +31630,7 @@ See \`config.log' for more details" "$LINENO" 5; }
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
@@ -32432,6 +32550,11 @@ if test "x$HAVE_WEBRTC" = "x1"; then :
else
ENABLE_WEBRTC=no
fi
+if test "x$HAVE_GSTREAMER" = "x1"; then :
+ ENABLE_GSTREAMER=yes
+else
+ ENABLE_GSTREAMER=no
+fi
if test "x$HAVE_TDB" = "x1"; then :
ENABLE_TDB=yes
else
@@ -32527,6 +32650,7 @@ echo "
Enable speex (resampler, AEC): ${ENABLE_SPEEX}
Enable soxr (resampler): ${ENABLE_SOXR}
Enable WebRTC echo canceller: ${ENABLE_WEBRTC}
+ Enable GStreamer-based RTP: ${ENABLE_GSTREAMER}
Enable gcov coverage: ${ENABLE_GCOV}
Enable unit tests: ${ENABLE_TESTS}
Database
diff --git a/configure.ac b/configure.ac
index 8278353..0ac5651 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,7 @@ AC_SUBST(PA_PROTOCOL_VERSION, 33)
# The stable ABI for client applications, for the version info x:y:z
# always will hold x=z
-AC_SUBST(LIBPULSE_VERSION_INFO, [21:1:21])
+AC_SUBST(LIBPULSE_VERSION_INFO, [21:2:21])
# A simplified, synchronous, ABI-stable interface for client
# applications, for the version info x:y:z always will hold x=z
@@ -1310,6 +1310,22 @@ AC_SUBST(HAVE_SYSTEMD_JOURNAL)
AM_CONDITIONAL([HAVE_SYSTEMD_JOURNAL], [test "x$HAVE_SYSTEMD_JOURNAL" = x1])
AS_IF([test "x$HAVE_SYSTEMD_JOURNAL" = "x1"], AC_DEFINE([HAVE_SYSTEMD_JOURNAL], 1, [Have SYSTEMDJOURNAL?]))
+#### GStreamer-based RTP support (optional) ####
+
+AC_ARG_ENABLE([gstreamer],
+ AS_HELP_STRING([--disable-gstreamer],[Disable optional GStreamer-based RTP support]))
+
+AS_IF([test "x$enable_gstreamer" != "xno"],
+ [PKG_CHECK_MODULES(GSTREAMER, [ gstreamer-1.0 gstreamer-app-1.0 gstreamer-rtp-1.0 gio-2.0 ],
+ HAVE_GSTREAMER=yes, HAVE_GSTREAMER=no)],
+ HAVE_GSTREAMER=no)
+
+AS_IF([test "x$enable_gstreamer" = "xyes" && test "x$HAVE_GSTREAMER" = "xno"],
+ [AC_MSG_ERROR([*** GStreamer 1.0 support not found])])
+
+AM_CONDITIONAL([HAVE_GSTREAMER], [test "x$HAVE_GSTREAMER" = xyes])
+AS_IF([test "x$HAVE_GSTREAMER" = "xyes"], AC_DEFINE([HAVE_GSTREAMER], 1, [Have GStreamer?]))
+
#### Build and Install man pages ####
AC_ARG_ENABLE([manpages],
@@ -1614,6 +1630,7 @@ AS_IF([test "x$HAVE_ADRIAN_EC" = "x1"], ENABLE_ADRIAN_EC=yes, ENABLE_ADRIAN_EC=n
AS_IF([test "x$HAVE_SPEEX" = "x1"], ENABLE_SPEEX=yes, ENABLE_SPEEX=no)
AS_IF([test "x$HAVE_SOXR" = "x1"], ENABLE_SOXR=yes, ENABLE_SOXR=no)
AS_IF([test "x$HAVE_WEBRTC" = "x1"], ENABLE_WEBRTC=yes, ENABLE_WEBRTC=no)
+AS_IF([test "x$HAVE_GSTREAMER" = "x1"], ENABLE_GSTREAMER=yes, ENABLE_GSTREAMER=no)
AS_IF([test "x$HAVE_TDB" = "x1"], ENABLE_TDB=yes, ENABLE_TDB=no)
AS_IF([test "x$HAVE_GDBM" = "x1"], ENABLE_GDBM=yes, ENABLE_GDBM=no)
AS_IF([test "x$HAVE_SIMPLEDB" = "x1"], ENABLE_SIMPLEDB=yes, ENABLE_SIMPLEDB=no)
@@ -1677,6 +1694,7 @@ echo "
Enable speex (resampler, AEC): ${ENABLE_SPEEX}
Enable soxr (resampler): ${ENABLE_SOXR}
Enable WebRTC echo canceller: ${ENABLE_WEBRTC}
+ Enable GStreamer-based RTP: ${ENABLE_GSTREAMER}
Enable gcov coverage: ${ENABLE_GCOV}
Enable unit tests: ${ENABLE_TESTS}
Database
diff --git a/debian/changelog b/debian/changelog
index d532f22..69f8ccd 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,19 @@
+pulseaudio (13.99.1-1) UNRELEASED; urgency=medium
+
+ * New upstream rc version, including those changes:
+ - default sink selection for a better user experience, ALSA UCM support,
+ disabling flat volumes by default, stream rescue moving to core,
+ GStreamer-based RTP support, and qpaeq moving to Python 3.
+ * debian/control:
+ - B-D on libgstreamer1.0-dev and libgstreamer-plugins-base1.0-dev,
+ needed to enable the gstreamer based RTP support
+ * debian/patches/qpaeq-Drop-unused-imports.patch,
+ debian/patches/qpaeq-use-python3-instead-of-python-2.patch,
+ debian/patches/daemon-conf-disable-flat-volumes-by-default.patch:
+ - dropped the changes included in the new version
+
+ -- Sebastien Bacher <seb128@ubuntu.com> Wed, 19 Feb 2020 18:34:48 +0100
+
pulseaudio (13.0-5) unstable; urgency=medium
* Fix removal of 00-disable-autospawn.conf.
diff --git a/debian/control b/debian/control
index 15011f9..9c25891 100644
--- a/debian/control
+++ b/debian/control
@@ -17,6 +17,8 @@ Build-Depends: debhelper-compat (= 12),
libcap-dev [linux-any],
libfftw3-dev,
libglib2.0-dev,
+ libgstreamer1.0-dev,
+ libgstreamer-plugins-base1.0-dev,
libgtk-3-dev,
libice-dev,
libjack-dev,
diff --git a/debian/patches/daemon-conf-disable-flat-volumes-by-default.patch b/debian/patches/daemon-conf-disable-flat-volumes-by-default.patch
deleted file mode 100644
index 680a818..0000000
--- a/debian/patches/daemon-conf-disable-flat-volumes-by-default.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From: Tanu Kaskinen <tanuk@iki.fi>
-Date: Mon, 23 Sep 2019 07:48:48 +0300
-Subject: daemon-conf: disable flat-volumes by default
-
-Almost all distributions patch the configuration to disable
-flat-volumes, because users tend to find the concept confusing (and it
-also causes nasty surprises when some application pushes the volume to
-100%). Let's remove the need for patching and disable the feature by
-default.
-
-Fixes: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/691
-(cherry picked from commit ba73faa4c05717d74fbfd17e8175731e60d8841d)
----
- man/pulse-daemon.conf.5.xml.in | 2 +-
- src/daemon/daemon-conf.c | 2 +-
- src/daemon/daemon.conf.in | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
-index f49fa9b..1436126 100644
---- a/man/pulse-daemon.conf.5.xml.in
-+++ b/man/pulse-daemon.conf.5.xml.in
-@@ -237,7 +237,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
- <p><opt>flat-volumes=</opt> Enable 'flat' volumes, i.e. where
- possible let the sink volume equal the maximum of the volumes of
- the inputs connected to it. Takes a boolean argument, defaults
-- to <opt>yes</opt>.</p>
-+ to <opt>no</opt>.</p>
- </option>
-
- </section>
-diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
-index 33cf7a7..e74b4ba 100644
---- a/src/daemon/daemon-conf.c
-+++ b/src/daemon/daemon-conf.c
-@@ -68,7 +68,7 @@ static const pa_daemon_conf default_conf = {
- .realtime_priority = 5, /* Half of JACK's default rtprio */
- .disallow_module_loading = false,
- .disallow_exit = false,
-- .flat_volumes = true,
-+ .flat_volumes = false,
- .exit_idle_time = 20,
- .scache_idle_time = 20,
- .script_commands = NULL,
-diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
-index a955523..480608e 100644
---- a/src/daemon/daemon.conf.in
-+++ b/src/daemon/daemon.conf.in
-@@ -60,7 +60,7 @@ ifelse(@HAVE_DBUS@, 1, [dnl
- ; enable-lfe-remixing = no
- ; lfe-crossover-freq = 0
-
--; flat-volumes = yes
-+; flat-volumes = no
-
- ifelse(@HAVE_SYS_RESOURCE_H@, 1, [dnl
- ; rlimit-fsize = -1
diff --git a/debian/patches/qpaeq-Drop-unused-imports.patch b/debian/patches/qpaeq-Drop-unused-imports.patch
deleted file mode 100644
index 823ba81..0000000
--- a/debian/patches/qpaeq-Drop-unused-imports.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From: Felipe Sateler <fsateler@debian.org>
-Date: Fri, 25 Oct 2019 08:34:59 -0300
-Subject: qpaeq: Drop unused imports
-
-Neither sip nor PyQt5 are used. From PyQt5 we only use the named imports just below
-Forwarded: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/197
----
- src/utils/qpaeq | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/src/utils/qpaeq b/src/utils/qpaeq
-index ac0daec..914aedf 100755
---- a/src/utils/qpaeq
-+++ b/src/utils/qpaeq
-@@ -18,7 +18,6 @@
-
- import os,math,sys
- try:
-- import PyQt5,sip
- from PyQt5 import QtWidgets,QtCore
- import dbus.mainloop.pyqt5
- import dbus
diff --git a/debian/patches/qpaeq-use-python3-instead-of-python-2.patch b/debian/patches/qpaeq-use-python3-instead-of-python-2.patch
deleted file mode 100644
index 9abe160..0000000
--- a/debian/patches/qpaeq-use-python3-instead-of-python-2.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From: Felipe Sateler <fsateler@debian.org>
-Date: Fri, 25 Oct 2019 08:39:03 -0300
-Subject: qpaeq: use python3 instead of python 2
-
-The script was already compatible, so lets just switch interpreter
-Forwarded: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/merge_requests/197
----
- src/utils/qpaeq | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/utils/qpaeq b/src/utils/qpaeq
-index 914aedf..7e01d87 100755
---- a/src/utils/qpaeq
-+++ b/src/utils/qpaeq
-@@ -1,4 +1,4 @@
--#!/usr/bin/env python
-+#!/usr/bin/env python3
- # qpaeq is a equalizer interface for pulseaudio's equalizer sinks
- # Copyright (C) 2009 Jason Newton <nevion@gmail.com
- #
diff --git a/debian/patches/series b/debian/patches/series
index 80a5590..e62843a 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,4 +1 @@
-qpaeq-Drop-unused-imports.patch
-qpaeq-use-python3-instead-of-python-2.patch
-daemon-conf-disable-flat-volumes-by-default.patch
disable-autospawn.patch
diff --git a/doxygen/Makefile.in b/doxygen/Makefile.in
index c7c0b85..3ea5da4 100644
--- a/doxygen/Makefile.in
+++ b/doxygen/Makefile.in
@@ -206,6 +206,8 @@ GREP = @GREP@
GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@
GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@
GSETTINGS_LIBS = @GSETTINGS_LIBS@
+GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@
+GSTREAMER_LIBS = @GSTREAMER_LIBS@
GTK30_CFLAGS = @GTK30_CFLAGS@
GTK30_LIBS = @GTK30_LIBS@
HAVE_AF_UNIX = @HAVE_AF_UNIX@
@@ -416,7 +418,6 @@ prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pulseconfdir = @pulseconfdir@
-runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
diff --git a/m4/gettext.m4 b/m4/gettext.m4
index be247bf..eef5073 100644
--- a/m4/gettext.m4
+++ b/m4/gettext.m4
@@ -1,16 +1,16 @@
-# gettext.m4 serial 66 (gettext-0.18.2)
-dnl Copyright (C) 1995-2014 Free Software Foundation, Inc.
+# gettext.m4 serial 68 (gettext-0.19.8)
+dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-dnl This file can can be used in projects which are not available under
+dnl This file can be used in projects which are not available under
dnl the GNU General Public License or the GNU Library General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
+dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Authors:
@@ -161,13 +161,18 @@ changequote([,])dnl
[AC_LANG_PROGRAM(
[[
#include <libintl.h>
-$gt_revision_test_code
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
extern int _nl_msg_cat_cntr;
extern int *_nl_domain_bindings;
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings)
+#else
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
+#endif
+$gt_revision_test_code
]],
[[
bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings
+return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
]])],
[eval "$gt_func_gnugettext_libc=yes"],
[eval "$gt_func_gnugettext_libc=no"])])
@@ -193,17 +198,22 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_b
[AC_LANG_PROGRAM(
[[
#include <libintl.h>
-$gt_revision_test_code
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
extern int _nl_msg_cat_cntr;
extern
#ifdef __cplusplus
"C"
#endif
const char *_nl_expand_alias (const char *);
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (""))
+#else
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
+#endif
+$gt_revision_test_code
]],
[[
bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
]])],
[eval "$gt_func_gnugettext_libintl=yes"],
[eval "$gt_func_gnugettext_libintl=no"])
@@ -214,17 +224,22 @@ return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_a
[AC_LANG_PROGRAM(
[[
#include <libintl.h>
-$gt_revision_test_code
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
extern int _nl_msg_cat_cntr;
extern
#ifdef __cplusplus
"C"
#endif
const char *_nl_expand_alias (const char *);
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias (""))
+#else
+#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0
+#endif
+$gt_revision_test_code
]],
[[
bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")
+return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION
]])],
[LIBINTL="$LIBINTL $LIBICONV"
LTLIBINTL="$LTLIBINTL $LTLIBICONV"
@@ -399,3 +414,7 @@ AC_DEFUN([AM_GNU_GETTEXT_NEED],
dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
+
+
+dnl Usage: AM_GNU_GETTEXT_REQUIRE_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_REQUIRE_VERSION], [])
diff --git a/m4/iconv.m4 b/m4/iconv.m4
index 4b29c5f..aa159c5 100644
--- a/m4/iconv.m4
+++ b/m4/iconv.m4
@@ -1,5 +1,5 @@
-# iconv.m4 serial 18 (gettext-0.18.2)
-dnl Copyright (C) 2000-2002, 2007-2014 Free Software Foundation, Inc.
+# iconv.m4 serial 19 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2007-2014, 2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -72,27 +72,33 @@ AC_DEFUN([AM_ICONV_LINK],
if test $am_cv_lib_iconv = yes; then
LIBS="$LIBS $LIBICONV"
fi
- AC_RUN_IFELSE(
- [AC_LANG_SOURCE([[
+ am_cv_func_iconv_works=no
+ for ac_iconv_const in '' 'const'; do
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[
#include <iconv.h>
#include <string.h>
-int main ()
-{
- int result = 0;
+
+#ifndef ICONV_CONST
+# define ICONV_CONST $ac_iconv_const
+#endif
+ ]],
+ [[int result = 0;
/* Test against AIX 5.1 bug: Failures are not distinguishable from successful
returns. */
{
iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
if (cd_utf8_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\342\202\254"; /* EURO SIGN */
+ static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_utf8_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 1;
@@ -105,14 +111,14 @@ int main ()
iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
if (cd_ascii_to_88591 != (iconv_t)(-1))
{
- static const char input[] = "\263";
+ static ICONV_CONST char input[] = "\263";
char buf[10];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_ascii_to_88591,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res == 0)
result |= 2;
@@ -124,14 +130,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304";
+ static ICONV_CONST char input[] = "\304";
static char buf[2] = { (char)0xDE, (char)0xAD };
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = 1;
char *outptr = buf;
size_t outbytesleft = 1;
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD)
result |= 4;
@@ -144,14 +150,14 @@ int main ()
iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
if (cd_88591_to_utf8 != (iconv_t)(-1))
{
- static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
char buf[50];
- const char *inptr = input;
+ ICONV_CONST char *inptr = input;
size_t inbytesleft = strlen (input);
char *outptr = buf;
size_t outbytesleft = sizeof (buf);
size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
+ &inptr, &inbytesleft,
&outptr, &outbytesleft);
if ((int)res > 0)
result |= 8;
@@ -171,17 +177,14 @@ int main ()
&& iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
result |= 16;
return result;
-}]])],
- [am_cv_func_iconv_works=yes],
- [am_cv_func_iconv_works=no],
- [
-changequote(,)dnl
- case "$host_os" in
- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
- *) am_cv_func_iconv_works="guessing yes" ;;
- esac
-changequote([,])dnl
- ])
+]])],
+ [am_cv_func_iconv_works=yes], ,
+ [case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac])
+ test "$am_cv_func_iconv_works" = no || break
+ done
LIBS="$am_save_LIBS"
])
case "$am_cv_func_iconv_works" in
diff --git a/m4/intlmacosx.m4 b/m4/intlmacosx.m4
index 8a045f6..aca924c 100644
--- a/m4/intlmacosx.m4
+++ b/m4/intlmacosx.m4
@@ -1,16 +1,16 @@
# intlmacosx.m4 serial 5 (gettext-0.18.2)
-dnl Copyright (C) 2004-2014 Free Software Foundation, Inc.
+dnl Copyright (C) 2004-2014, 2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-dnl This file can can be used in projects which are not available under
+dnl This file can be used in projects which are not available under
dnl the GNU General Public License or the GNU Library General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
+dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Checks for special options needed on Mac OS X.
diff --git a/m4/lib-ld.m4 b/m4/lib-ld.m4
index ddc569f..6209de6 100644
--- a/m4/lib-ld.m4
+++ b/m4/lib-ld.m4
@@ -1,5 +1,5 @@
# lib-ld.m4 serial 6
-dnl Copyright (C) 1996-2003, 2009-2014 Free Software Foundation, Inc.
+dnl Copyright (C) 1996-2003, 2009-2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/lib-link.m4 b/m4/lib-link.m4
index 3522d99..2f51855 100644
--- a/m4/lib-link.m4
+++ b/m4/lib-link.m4
@@ -1,5 +1,5 @@
# lib-link.m4 serial 26 (gettext-0.18.2)
-dnl Copyright (C) 2001-2014 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/lib-prefix.m4 b/m4/lib-prefix.m4
index 31f49e4..1601cea 100644
--- a/m4/lib-prefix.m4
+++ b/m4/lib-prefix.m4
@@ -1,5 +1,5 @@
# lib-prefix.m4 serial 7 (gettext-0.18)
-dnl Copyright (C) 2001-2005, 2008-2014 Free Software Foundation, Inc.
+dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index c81e669..a644432 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -728,6 +728,7 @@ _LT_CONFIG_SAVE_COMMANDS([
cat <<_LT_EOF >> "$cfgfile"
#! $SHELL
# Generated automatically by $as_me ($PACKAGE) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
# Provide generalized library-building support services.
@@ -2866,6 +2867,9 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# before this can be enabled.
hardcode_into_libs=yes
+ # Add ABI-specific directories to the system library path.
+ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
+
# Ideally, we could use ldconfig to report *all* directores which are
# searched for libraries, however this is still not possible. Aside from not
# being certain /sbin/ldconfig is available, command
@@ -2874,7 +2878,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
# appending ld.so.conf contents (and includes) to the search path.
if test -f /etc/ld.so.conf; then
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
fi
# We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -2886,18 +2890,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
dynamic_linker='GNU/Linux ld.so'
;;
-netbsdelf*-gnu)
- version_type=linux
- need_lib_prefix=no
- need_version=no
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
- soname_spec='${libname}${release}${shared_ext}$major'
- shlibpath_var=LD_LIBRARY_PATH
- shlibpath_overrides_runpath=no
- hardcode_into_libs=yes
- dynamic_linker='NetBSD ld.elf_so'
- ;;
-
netbsd*)
version_type=sunos
need_lib_prefix=no
@@ -3557,7 +3549,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
lt_cv_deplibs_check_method=pass_all
;;
-netbsd* | netbsdelf*-gnu)
+netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
@@ -4063,8 +4055,7 @@ _LT_EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
nlist=conftest.nm
- $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
- if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
# Try sorting and uniquifying the output.
if sort "$nlist" | uniq > "$nlist"T; then
mv -f "$nlist"T "$nlist"
@@ -4436,7 +4427,7 @@ m4_if([$1], [CXX], [
;;
esac
;;
- netbsd* | netbsdelf*-gnu)
+ netbsd*)
;;
*qnx* | *nto*)
# QNX uses GNU C++, but need to define -shared option too, otherwise
@@ -4948,9 +4939,6 @@ m4_if([$1], [CXX], [
;;
esac
;;
- linux* | k*bsd*-gnu | gnu*)
- _LT_TAGVAR(link_all_deplibs, $1)=no
- ;;
*)
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
;;
@@ -5013,9 +5001,6 @@ dnl Note also adjust exclude_expsyms for C++ above.
openbsd* | bitrig*)
with_gnu_ld=no
;;
- linux* | k*bsd*-gnu | gnu*)
- _LT_TAGVAR(link_all_deplibs, $1)=no
- ;;
esac
_LT_TAGVAR(ld_shlibs, $1)=yes
@@ -5270,7 +5255,7 @@ _LT_EOF
fi
;;
- netbsd* | netbsdelf*-gnu)
+ netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -5791,7 +5776,6 @@ _LT_EOF
if test yes = "$lt_cv_irix_exported_symbol"; then
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
fi
- _LT_TAGVAR(link_all_deplibs, $1)=no
else
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
@@ -5813,7 +5797,7 @@ _LT_EOF
esac
;;
- netbsd* | netbsdelf*-gnu)
+ netbsd*)
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -6439,7 +6423,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
GXX=no
@@ -6814,7 +6798,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -6879,7 +6863,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
;;
*)
if test yes = "$GXX"; then
@@ -7218,7 +7202,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# FIXME: insert proper C++ library support
@@ -7302,7 +7286,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
else
# g++ 2.7 appears to require '-G' NOT '-shared' on this
# platform.
@@ -7313,7 +7297,7 @@ if test yes != "$_lt_caught_CXX_error"; then
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
# linking a shared library.
- output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
fi
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
diff --git a/m4/nls.m4 b/m4/nls.m4
index 53cdc8b..003704c 100644
--- a/m4/nls.m4
+++ b/m4/nls.m4
@@ -1,5 +1,5 @@
# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2014 Free Software Foundation,
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
dnl Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
diff --git a/m4/po.m4 b/m4/po.m4
index 84659ea..c5a2f6b 100644
--- a/m4/po.m4
+++ b/m4/po.m4
@@ -1,16 +1,16 @@
-# po.m4 serial 22 (gettext-0.19)
-dnl Copyright (C) 1995-2014 Free Software Foundation, Inc.
+# po.m4 serial 24 (gettext-0.19)
+dnl Copyright (C) 1995-2014, 2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-dnl This file can can be used in projects which are not available under
+dnl This file can be used in projects which are not available under
dnl the GNU General Public License or the GNU Library General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
+dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Authors:
diff --git a/m4/progtest.m4 b/m4/progtest.m4
index b499f79..9ace7c3 100644
--- a/m4/progtest.m4
+++ b/m4/progtest.m4
@@ -1,16 +1,16 @@
# progtest.m4 serial 7 (gettext-0.18.2)
-dnl Copyright (C) 1996-2003, 2005, 2008-2014 Free Software Foundation, Inc.
+dnl Copyright (C) 1996-2003, 2005, 2008-2016 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-dnl This file can can be used in projects which are not available under
+dnl This file can be used in projects which are not available under
dnl the GNU General Public License or the GNU Library General Public
dnl License but which still want to provide support for the GNU gettext
dnl functionality.
dnl Please note that the actual code of the GNU gettext library is covered
dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
+dnl gettext package is covered by the GNU General Public License.
dnl They are *not* in the public domain.
dnl Authors:
diff --git a/man/Makefile.in b/man/Makefile.in
index 0e4cc9d..0026d18 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -255,6 +255,8 @@ GREP = @GREP@
GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@
GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@
GSETTINGS_LIBS = @GSETTINGS_LIBS@
+GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@
+GSTREAMER_LIBS = @GSTREAMER_LIBS@
GTK30_CFLAGS = @GTK30_CFLAGS@
GTK30_LIBS = @GTK30_LIBS@
HAVE_AF_UNIX = @HAVE_AF_UNIX@
@@ -465,7 +467,6 @@ prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pulseconfdir = @pulseconfdir@
-runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
diff --git a/man/default.pa.5 b/man/default.pa.5
index 11438a5..08885a0 100644
--- a/man/default.pa.5
+++ b/man/default.pa.5
@@ -4,12 +4,12 @@ default.pa \- PulseAudio Sound Server Startup Script
.SH SYNOPSIS
\fB\fI~/.config/pulse/default.pa\fB
-\fI/usr/local/etc/pulse/default.pa\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/default.pa\fB
-\fI/usr/local/etc/pulse/system.pa\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/system.pa\fB
\f1
.SH DESCRIPTION
-The PulseAudio sound server interprets a configuration script on startup, which is mainly used to define the set of modules to load. When PulseAudio runs in the per-user mode and \fI~/.config/pulse/default.pa\f1 exists, that file is used. When PulseAudio runs in the per-user mode and that file doesn't exist, \fI/usr/local/etc/pulse/default.pa\f1 is used. When PulseAudio runs as a system service, \fI/usr/local/etc/pulse/system.pa\f1 is used.
+The PulseAudio sound server interprets a configuration script on startup, which is mainly used to define the set of modules to load. When PulseAudio runs in the per-user mode and \fI~/.config/pulse/default.pa\f1 exists, that file is used. When PulseAudio runs in the per-user mode and that file doesn't exist, \fI/home/arun/local/pulseaudio/etc/pulse/default.pa\f1 is used. When PulseAudio runs as a system service, \fI/home/arun/local/pulseaudio/etc/pulse/system.pa\f1 is used.
The script should contain directives in the PulseAudio CLI language, as documented in \fBpulse-cli-syntax(5)\f1.
.SH AUTHORS
diff --git a/man/pax11publish.1 b/man/pax11publish.1
index ec241b9..740841a 100644
--- a/man/pax11publish.1
+++ b/man/pax11publish.1
@@ -32,7 +32,7 @@ Read the PulseAudio server credentials currently set on the X11 root window and
Similar to \fB-d\f1, however dumps them in a Bourne shell compatible format so they may be used together with the \fIeval\f1 shell command to set the $PULSE_SERVER, $PULSE_SINK, $PULSE_SOURCE environment variables. Also reads the authentication cookie from the root window and stores it in \fI~/.config/pulse/cookie\f1.
.TP
\fB-e\f1
-Export the currently locally used sound server, sink, source configuration to the X11 root window. This takes the data from the $PULSE_SERVER, $PULSE_SINK, $PULSE_SOURCE environment variables and combines them with the data from \fI~/.config/pulse/client.conf\f1 (or \fI/usr/local/etc/pulse/client.conf\f1 if that file does not exist). If specific options are passed on the command line (\fB-S\f1, \fB-O\f1, \fB-I\f1, \fB-c\f1, see below), they take precedence. Also uploads the local authentication cookie \fI~/.config/pulse/cookie\f1 to the X11 server.
+Export the currently locally used sound server, sink, source configuration to the X11 root window. This takes the data from the $PULSE_SERVER, $PULSE_SINK, $PULSE_SOURCE environment variables and combines them with the data from \fI~/.config/pulse/client.conf\f1 (or \fI/home/arun/local/pulseaudio/etc/pulse/client.conf\f1 if that file does not exist). If specific options are passed on the command line (\fB-S\f1, \fB-O\f1, \fB-I\f1, \fB-c\f1, see below), they take precedence. Also uploads the local authentication cookie \fI~/.config/pulse/cookie\f1 to the X11 server.
.TP
\fB-r\f1
Removes the configured PulseAudio configuration from the X11 root window.
diff --git a/man/pulse-cli-syntax.5 b/man/pulse-cli-syntax.5
index 879ce2c..acaec39 100644
--- a/man/pulse-cli-syntax.5
+++ b/man/pulse-cli-syntax.5
@@ -4,9 +4,9 @@ pulse-cli-syntax \- PulseAudio Command Line Interface Syntax
.SH SYNOPSIS
\fB\fI~/.config/pulse/default.pa\fB
-\fI/usr/local/etc/pulse/default.pa\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/default.pa\fB
-\fI/usr/local/etc/pulse/system.pa\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/system.pa\fB
\f1
.SH DESCRIPTION
PulseAudio provides a simple command line language used by configuration scripts, the pacmd interactive shell, and the modules module-cli and module-cli-protocol-{unix,tcp}. Empty lines and lines beginning with a hashmark (#) are silently ignored. Several commands are supported.
diff --git a/man/pulse-client.conf.5 b/man/pulse-client.conf.5
index 7bddd74..fdf3888 100644
--- a/man/pulse-client.conf.5
+++ b/man/pulse-client.conf.5
@@ -6,12 +6,12 @@ pulse-client.conf \- PulseAudio client configuration file
\fI~/.config/pulse/client.conf.d/*.conf\fB
-\fI/usr/local/etc/pulse/client.conf\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/client.conf\fB
-\fI/usr/local/etc/pulse/client.conf.d/*.conf\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/client.conf.d/*.conf\fB
\f1
.SH DESCRIPTION
-The PulseAudio client library reads configuration directives from a configuration file on startup. If the per-user file \fI~/.config/pulse/client.conf\f1 exists, it is used, otherwise the system configuration file \fI/usr/local/etc/pulse/client.conf\f1 is used. In addition to those main files, configuration directives can also be put in files under directories \fI~/.config/pulse/client.conf.d/\f1 and \fI/usr/local/etc/pulse/client.conf.d/\f1. Those files have to have the .conf file name extension, but otherwise the file names can be chosen freely. The files under client.conf.d are processed in alphabetical order. In case the same option is set in multiple files, the last file to set an option overrides earlier files. The main client.conf file is processed first, so options set in files under client.conf.d override the main file.
+The PulseAudio client library reads configuration directives from a configuration file on startup. If the per-user file \fI~/.config/pulse/client.conf\f1 exists, it is used, otherwise the system configuration file \fI/home/arun/local/pulseaudio/etc/pulse/client.conf\f1 is used. In addition to those main files, configuration directives can also be put in files under directories \fI~/.config/pulse/client.conf.d/\f1 and \fI/home/arun/local/pulseaudio/etc/pulse/client.conf.d/\f1. Those files have to have the .conf file name extension, but otherwise the file names can be chosen freely. The files under client.conf.d are processed in alphabetical order. In case the same option is set in multiple files, the last file to set an option overrides earlier files. The main client.conf file is processed first, so options set in files under client.conf.d override the main file.
The configuration file is a simple collection of variable declarations. If the configuration file parser encounters either ; or # it ignores the rest of the line until its end.
diff --git a/man/pulse-daemon.conf.5 b/man/pulse-daemon.conf.5
index ae99147..b2f34ac 100644
--- a/man/pulse-daemon.conf.5
+++ b/man/pulse-daemon.conf.5
@@ -6,12 +6,12 @@ pulse-daemon.conf \- PulseAudio daemon configuration file
\fI~/.config/pulse/daemon.conf.d/*.conf\fB
-\fI/usr/local/etc/pulse/daemon.conf\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/daemon.conf\fB
-\fI/usr/local/etc/pulse/daemon.conf.d/*.conf\fB
+\fI/home/arun/local/pulseaudio/etc/pulse/daemon.conf.d/*.conf\fB
\f1
.SH DESCRIPTION
-The PulseAudio sound server reads configuration directives from a configuration file on startup. If the per-user file \fI~/.config/pulse/daemon.conf\f1 exists, it is used, otherwise the system configuration file \fI/usr/local/etc/pulse/daemon.conf\f1 is used. In addition to those main files, configuration directives can also be put in files under directories \fI~/.config/pulse/daemon.conf.d/\f1 and \fI/usr/local/etc/pulse/daemon.conf.d/\f1. Those files have to have the .conf file name extension, but otherwise the file names can be chosen freely. The files under daemon.conf.d are processed in alphabetical order. In case the same option is set in multiple files, the last file to set an option overrides earlier files. The main daemon.conf file is processed first, so options set in files under daemon.conf.d override the main file.
+The PulseAudio sound server reads configuration directives from a configuration file on startup. If the per-user file \fI~/.config/pulse/daemon.conf\f1 exists, it is used, otherwise the system configuration file \fI/home/arun/local/pulseaudio/etc/pulse/daemon.conf\f1 is used. In addition to those main files, configuration directives can also be put in files under directories \fI~/.config/pulse/daemon.conf.d/\f1 and \fI/home/arun/local/pulseaudio/etc/pulse/daemon.conf.d/\f1. Those files have to have the .conf file name extension, but otherwise the file names can be chosen freely. The files under daemon.conf.d are processed in alphabetical order. In case the same option is set in multiple files, the last file to set an option overrides earlier files. The main daemon.conf file is processed first, so options set in files under daemon.conf.d override the main file.
Please note that the server also reads a configuration script on startup. See \fBdefault.pa(5)\f1.
@@ -36,7 +36,11 @@ For the settings that take a boolean argument the values \fBtrue\f1, \fByes\f1,
.TP
\fBremixing-use-all-sink-channels=\f1 If enabled, use all sink channels when remixing. Otherwise, remix to the minimal set of sink channels needed to reproduce all of the source channels. (This has no effect on LFE remixing.) Defaults to \fByes\f1.
.TP
-\fBenable-lfe-remixing=\f1 If disabled when upmixing or downmixing ignore LFE channels. When this option is disabled 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 \fBno\f1.
+\fBenable-lfe-remixing=\f1 This is a way to set \fBremixing-produce-lfe\f1 and \fBremixing-consume-lfe\f1 to the same value at once. This option only exists for backward compatibility and may be removed in a future version of PulseAudio.
+.TP
+\fBremixing-produce-lfe=\f1 If enabled, and the sink input does not have the LFE channel, synthesize the output LFE channel as a (lowpass-filtered, if \fBlfe-crossover-freq\f1 is not 0) average of all input channels. Also, when \fBlfe-crossover-freq\f1 is not 0, filter out low frequencies from other channels while producing a synthetic LFE output. If disabled, the output LFE channel will only get a signal when an input LFE channel is available as well. Defaults to \fBno\f1.
+.TP
+\fBremixing-consume-lfe=\f1 If enabled, and the sink does not have an LFE channel, redirect the input LFE channel (if any) to other channels. If disabled, the input LFE channel will remain unused unless the sink has the LFE channel as well. Defaults to \fBno\f1.
.TP
\fBlfe-crossover-freq=\f1 The crossover frequency (in Hz) for the LFE filter. Set it to 0 to disable the LFE filter. Defaults to 0.
.TP
@@ -56,7 +60,9 @@ For the settings that take a boolean argument the values \fBtrue\f1, \fByes\f1,
.TP
\fBlock-memory=\f1 Locks the entire PulseAudio process into memory. While this might increase drop-out safety when used in conjunction with real-time scheduling this takes away a lot of memory from other processes and might hence considerably slow down your system. Defaults to \fBno\f1.
.TP
-\fBflat-volumes=\f1 Enable 'flat' volumes, i.e. where possible let the sink volume equal the maximum of the volumes of the inputs connected to it. Takes a boolean argument, defaults to \fByes\f1.
+\fBflat-volumes=\f1 Enable 'flat' volumes, i.e. where possible let the sink volume equal the maximum of the volumes of the inputs connected to it. Takes a boolean argument, defaults to \fBno\f1.
+.TP
+\fBrescue-streams=\f1 Enable rescuing of streams if the used sink or source becomes unavailable. Takes a boolean argument. If set to \fByes\f1, pulseaudio will try to move the streams from a sink or source that becomes unavailable to the default sink or source. If set to \fBno\f1, streams will be killed if the corresponding sink or source disappears. Defaults to \fByes\f1.
.SH SCHEDULING
.TP
\fBhigh-priority=\f1 Renice the daemon after startup to become a high-priority process. This a good idea if you experience drop-outs during playback. However, this is a certain security issue, since it works when called SUID root only, or RLIMIT_NICE is used. root is dropped immediately after gaining the nice level on startup, thus it is presumably safe. See \fBpulseaudio(1)\f1 for more information. Takes a boolean argument, defaults to \fByes\f1. The \fB--high-priority\f1 command line option takes precedence.
@@ -79,7 +85,7 @@ When PulseAudio runs in the system mode, automatic exit is always disabled, so t
.TP
\fBdl-search-path=\f1 The path where to look for dynamic shared objects (DSOs/plugins). You may specify more than one path separated by colons. The default path depends on compile time settings. The \fB--dl-search-path\f1 command line option takes precedence.
.TP
-\fBdefault-script-file=\f1 The default configuration script file to load. Specify an empty string for not loading a default script file. The default behaviour is to load \fI~/.config/pulse/default.pa\f1, and if that file does not exist fall back to the system wide installed version \fI/usr/local/etc/pulse/default.pa\f1. If run in system-wide mode the file \fI/usr/local/etc/pulse/system.pa\f1 is used instead. If \fB-n\f1 is passed on the command line or \fBdefault-script-file=\f1 is disabled the default configuration script is ignored.
+\fBdefault-script-file=\f1 The default configuration script file to load. Specify an empty string for not loading a default script file. The default behaviour is to load \fI~/.config/pulse/default.pa\f1, and if that file does not exist fall back to the system wide installed version \fI/home/arun/local/pulseaudio/etc/pulse/default.pa\f1. If run in system-wide mode the file \fI/home/arun/local/pulseaudio/etc/pulse/system.pa\f1 is used instead. If \fB-n\f1 is passed on the command line or \fBdefault-script-file=\f1 is disabled the default configuration script is ignored.
.TP
\fBload-default-script-file=\f1 Load the default configuration script file as specified in \fBdefault-script-file=\f1. Defaults to \fByes\f1.
.SH LOGGING
diff --git a/man/pulse-daemon.conf.5.xml.in b/man/pulse-daemon.conf.5.xml.in
index f49fa9b..e64b20f 100644
--- a/man/pulse-daemon.conf.5.xml.in
+++ b/man/pulse-daemon.conf.5.xml.in
@@ -147,13 +147,28 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
</option>
<option>
- <p><opt>enable-lfe-remixing=</opt> If disabled when upmixing or
- downmixing ignore LFE channels. When this option is disabled 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 <opt>no</opt>.</p>
+ <p><opt>enable-lfe-remixing=</opt> This is a way to set
+ <opt>remixing-produce-lfe</opt> and <opt>remixing-consume-lfe</opt>
+ to the same value at once. This option only exists for backward
+ compatibility and may be removed in a future version of PulseAudio.</p>
+ </option>
+
+ <option>
+ <p><opt>remixing-produce-lfe=</opt> If enabled, and the sink input
+ does not have the LFE channel, synthesize the output LFE channel
+ as a (lowpass-filtered, if <opt>lfe-crossover-freq</opt> is not 0)
+ average of all input channels. Also, when <opt>lfe-crossover-freq</opt>
+ is not 0, filter out low frequencies from other channels while
+ producing a synthetic LFE output. If disabled, the output LFE channel
+ will only get a signal when an input LFE channel is available as well.
+ Defaults to <opt>no</opt>.</p>
+ </option>
+
+ <option>
+ <p><opt>remixing-consume-lfe=</opt> If enabled, and the sink does not
+ have an LFE channel, redirect the input LFE channel (if any) to other
+ channels. If disabled, the input LFE channel will remain unused unless
+ the sink has the LFE channel as well. Defaults to <opt>no</opt>.</p>
</option>
<option>
@@ -237,7 +252,16 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
<p><opt>flat-volumes=</opt> Enable 'flat' volumes, i.e. where
possible let the sink volume equal the maximum of the volumes of
the inputs connected to it. Takes a boolean argument, defaults
- to <opt>yes</opt>.</p>
+ to <opt>no</opt>.</p>
+ </option>
+
+ <option>
+ <p><opt>rescue-streams=</opt> Enable rescuing of streams if the
+ used sink or source becomes unavailable. Takes a boolean argument.
+ If set to <opt>yes</opt>, pulseaudio will try to move the streams
+ from a sink or source that becomes unavailable to the default sink
+ or source. If set to <opt>no</opt>, streams will be killed if the
+ corresponding sink or source disappears. Defaults to <opt>yes</opt>.</p>
</option>
</section>
diff --git a/man/pulseaudio.1 b/man/pulseaudio.1
index 9537ab3..27aa054 100644
--- a/man/pulseaudio.1
+++ b/man/pulseaudio.1
@@ -63,10 +63,10 @@ Daemonize after startup, i.e. detach from the terminal. Note that when running a
Fail startup when any of the commands specified in the startup script \fIdefault.pa\f1 (see below) fails.
.TP
\fB--high-priority\f1\fI[=BOOL]\f1
-Try to acquire a high Unix nice level. This will only succeed if the calling user has a non-zero RLIMIT_NICE resource limit set (on systems that support this), or we're called SUID root (see below), or we are configure to be run as system daemon (see \fI--system\f1 above). It is recommended to enable this, since it is only a negligible security risk (see below).
+Try to acquire a high Unix nice level. This will only succeed if the calling user has a non-zero RLIMIT_NICE resource limit set (on systems that support this), or we're configured to be run as system daemon (see \fI--system\f1 above). It is recommended to enable this, since it is only a negligible security risk (see below).
.TP
\fB--realtime\f1\fI[=BOOL]\f1
-Try to acquire a real-time scheduling for PulseAudio's I/O threads. This will only succeed if the calling user has a non-zero RLIMIT_RTPRIO resource limit set (on systems that support this), or we're called SUID root (see below), or we are configure to be run as system daemon (see \fI--system\f1 above). It is recommended to enable this only for trusted users, since it is a major security risk (see below).
+Try to acquire a real-time scheduling for PulseAudio's I/O threads. This will only succeed if the calling user has a non-zero RLIMIT_RTPRIO resource limit set (on systems that support this), or rtkit is available and allows PulseAudio to enable real-time scheduling, or we are configured to be run as system daemon (see \fI--system\f1 above).
.TP
\fB--disallow-module-loading\f1\fI[=BOOL]\f1
Disallow module loading after startup. This is a security feature since it disallows additional module loading during runtime and on user request. It is highly recommended when \fI--system\f1 is used (see above). Note however, that this breaks certain features like automatic module loading on hot plug.
@@ -132,11 +132,11 @@ Open a command interpreter on STDIN/STDOUT after startup. This may be used to co
\fB-n\f1
Don't load default script file \fIdefault.pa\f1 (see below) on startup. Useful in conjunction with \fB-C\f1 or \fB--file\f1.
.SH FILES
-\fI~/.config/pulse/daemon.conf\f1, \fI/usr/local/etc/pulse/daemon.conf\f1: configuration settings for the PulseAudio daemon. If the version in the user's home directory does not exist the global configuration file is loaded. See \fBpulse-daemon.conf(5)\f1 for more information.
+\fI~/.config/pulse/daemon.conf\f1, \fI/home/arun/local/pulseaudio/etc/pulse/daemon.conf\f1: configuration settings for the PulseAudio daemon. If the version in the user's home directory does not exist the global configuration file is loaded. See \fBpulse-daemon.conf(5)\f1 for more information.
-\fI~/.config/pulse/default.pa\f1, \fI/usr/local/etc/pulse/default.pa\f1: the default configuration script to execute when the PulseAudio daemon is started. If the version in the user's home directory does not exist the global configuration script is loaded. See \fBdefault.pa(5)\f1 for more information.
+\fI~/.config/pulse/default.pa\f1, \fI/home/arun/local/pulseaudio/etc/pulse/default.pa\f1: the default configuration script to execute when the PulseAudio daemon is started. If the version in the user's home directory does not exist the global configuration script is loaded. See \fBdefault.pa(5)\f1 for more information.
-\fI~/.config/pulse/client.conf\f1, \fI/usr/local/etc/pulse/client.conf\f1: configuration settings for PulseAudio client applications. If the version in the user's home directory does not exist the global configuration file is loaded. See \fBpulse-client.conf(5)\f1 for more information.
+\fI~/.config/pulse/client.conf\f1, \fI/home/arun/local/pulseaudio/etc/pulse/client.conf\f1: configuration settings for PulseAudio client applications. If the version in the user's home directory does not exist the global configuration file is loaded. See \fBpulse-client.conf(5)\f1 for more information.
.SH SIGNALS
\fISIGINT, SIGTERM\f1: the PulseAudio daemon will shut down (Same as \fB--kill\f1).
@@ -146,21 +146,13 @@ Don't load default script file \fIdefault.pa\f1 (see below) on startup. Useful i
\fISIGUSR2\f1: load module-cli-protocol-unix, allowing runtime reconfiguration via a AF_UNIX socket. See \fBpacmd(1)\f1 for more information.
.SH UNIX GROUPS AND USERS
-Group \fIpulse-rt\f1: if the PulseAudio binary is marked SUID root, then membership of the calling user in this group decides whether real-time and/or high-priority scheduling is enabled. Please note that enabling real-time scheduling is a security risk (see below).
-
Group \fIpulse-access\f1: if PulseAudio is running as a system daemon (see \fB--system\f1 above) access is granted to members of this group when they connect via AF_UNIX sockets. If PulseAudio is running as a user daemon this group has no meaning.
User \fIpulse\f1, group \fIpulse\f1: if PulseAudio is running as a system daemon (see \fB--system\f1 above) and is started as root the daemon will drop privileges and become a normal user process using this user and group. If PulseAudio is running as a user daemon this user and group has no meaning.
.SH REAL-TIME AND HIGH-PRIORITY SCHEDULING
-To minimize the risk of drop-outs during playback it is recommended to run PulseAudio with real-time scheduling if the underlying platform supports it. This decouples the scheduling latency of the PulseAudio daemon from the system load and is thus the best way to make sure that PulseAudio always gets CPU time when it needs it to refill the hardware playback buffers. Unfortunately this is a security risk on most systems, since PulseAudio runs as user process, and giving realtime scheduling privileges to a user process always comes with the risk that the user misuses it to lock up the system -- which is possible since making a process real-time effectively disables preemption.
-
-To minimize the risk PulseAudio by default does not enable real-time scheduling. It is however recommended to enable it on trusted systems. To do that start PulseAudio with \fB--realtime\f1 (see above) or enabled the appropriate option in \fIdaemon.conf\f1. Since acquiring realtime scheduling is a privileged operation on most systems, some special changes to the system configuration need to be made to allow them to the calling user. Two options are available:
-
-On newer Linux systems the system resource limit RLIMIT_RTPRIO (see \fBsetrlimit(2)\f1 for more information) can be used to allow specific users to acquire real-time scheduling. This can be configured in \fI/etc/security/limits.conf\f1, a resource limit of 9 is recommended.
-
-Alternatively, the SUID root bit can be set for the PulseAudio binary. Then, the daemon will drop root privileges immediately on startup, however retain the CAP_NICE capability (on systems that support it), but only if the calling user is a member of the \fIpulse-rt\f1 group (see above). For all other users all capabilities are dropped immediately. The advantage of this solution is that the real-time privileges are only granted to the PulseAudio daemon -- not to all the user's processes.
+To minimize the risk of drop-outs during playback it is recommended to run PulseAudio with real-time scheduling if the underlying platform supports it. This decouples the scheduling latency of the PulseAudio daemon from the system load and is thus the best way to make sure that PulseAudio always gets CPU time when it needs it to refill the hardware playback buffers. Unfortunately this can be a security risk on some systems, since PulseAudio runs as user process, and giving realtime scheduling privileges to a user always comes with the risk that the user misuses it to lock up the system -- which is possible since making a process real-time effectively disables preemption. To solve this problem, PulseAudio uses rtkit to safely acquire real-time scheduling when available.
-Alternatively, if the risk of locking up the machine is considered too big to enable real-time scheduling, high-priority scheduling can be enabled instead (i.e. negative nice level). This can be enabled by passing \fB--high-priority\f1 (see above) when starting PulseAudio and may also be enabled with the appropriate option in \fIdaemon.conf\f1. Negative nice levels can only be enabled when the appropriate resource limit RLIMIT_NICE is set (see \fBsetrlimit(2)\f1 for more information), possibly configured in \fI/etc/security/limits.conf\f1. A resource limit of 31 (corresponding with nice level -11) is recommended.
+If the risk of locking up the machine is considered too big to enable real-time scheduling, high-priority scheduling can be enabled instead (i.e. negative nice level). This can be enabled by passing \fB--high-priority\f1 (see above) when starting PulseAudio and may also be enabled with the appropriate option in \fIdaemon.conf\f1. Negative nice levels can only be enabled when the appropriate resource limit RLIMIT_NICE is set (see \fBsetrlimit(2)\f1 for more information), possibly configured in \fI/etc/security/limits.conf\f1. A resource limit of 31 (corresponding with nice level -11) is recommended.
.SH ENVIRONMENT VARIABLES
The PulseAudio client libraries check for the existence of the following environment variables and change their local configuration accordingly:
diff --git a/man/pulseaudio.1.xml.in b/man/pulseaudio.1.xml.in
index 824eddb..fdfb6e7 100644
--- a/man/pulseaudio.1.xml.in
+++ b/man/pulseaudio.1.xml.in
@@ -149,7 +149,7 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
<optdesc><p>Try to acquire a high Unix nice level. This will
only succeed if the calling user has a non-zero RLIMIT_NICE
resource limit set (on systems that support this), or we're
- called SUID root (see below), or we are configure to be run as
+ configured to be run as
system daemon (see <arg>--system</arg> above). It is recommended
to enable this, since it is only a negligible security risk (see
below).</p></optdesc>
@@ -161,11 +161,9 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
<optdesc><p>Try to acquire a real-time scheduling for
PulseAudio's I/O threads. This will only succeed if the calling
user has a non-zero RLIMIT_RTPRIO resource limit set (on systems
- that support this), or we're called SUID root (see below), or we
- are configure to be run as system daemon (see
- <arg>--system</arg> above). It is recommended to enable this
- only for trusted users, since it is a major security risk (see
- below).</p></optdesc>
+ that support this), or rtkit is available and allows PulseAudio
+ to enable real-time scheduling, or we are configured to be run as
+ system daemon (see <arg>--system</arg> above).</p></optdesc>
</option>
<option>
@@ -400,12 +398,6 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
<section name="UNIX Groups and users">
- <p>Group <arg>pulse-rt</arg>: if the PulseAudio binary is marked
- SUID root, then membership of the calling user in this group
- decides whether real-time and/or high-priority scheduling is
- enabled. Please note that enabling real-time scheduling is a
- security risk (see below).</p>
-
<p>Group <arg>pulse-access</arg>: if PulseAudio is running as a system
daemon (see <opt>--system</opt> above) access is granted to
members of this group when they connect via AF_UNIX sockets. If
@@ -426,38 +418,15 @@ License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
latency of the PulseAudio daemon from the system load and is thus
the best way to make sure that PulseAudio always gets CPU time
when it needs it to refill the hardware playback
- buffers. Unfortunately this is a security risk on most systems,
+ buffers. Unfortunately this can be a security risk on some systems,
since PulseAudio runs as user process, and giving realtime
- scheduling privileges to a user process always comes with the risk
+ scheduling privileges to a user always comes with the risk
that the user misuses it to lock up the system -- which is
possible since making a process real-time effectively disables
- preemption.</p>
-
- <p>To minimize the risk PulseAudio by default does not enable
- real-time scheduling. It is however recommended to enable it
- on trusted systems. To do that start PulseAudio with
- <opt>--realtime</opt> (see above) or enabled the appropriate option in
- <file>daemon.conf</file>. Since acquiring realtime scheduling is a
- privileged operation on most systems, some special changes to the
- system configuration need to be made to allow them to the calling
- user. Two options are available:</p>
-
- <p>On newer Linux systems the system resource limit RLIMIT_RTPRIO
- (see <manref name="setrlimit" section="2"/> for more information)
- can be used to allow specific users to acquire real-time
- scheduling. This can be configured in
- <file>/etc/security/limits.conf</file>, a resource limit of 9 is recommended.</p>
-
- <p>Alternatively, the SUID root bit can be set for the PulseAudio
- binary. Then, the daemon will drop root privileges immediately on
- startup, however retain the CAP_NICE capability (on systems that
- support it), but only if the calling user is a member of the
- <arg>pulse-rt</arg> group (see above). For all other users all
- capabilities are dropped immediately. The advantage of this
- solution is that the real-time privileges are only granted to the
- PulseAudio daemon -- not to all the user's processes.</p>
-
- <p>Alternatively, if the risk of locking up the machine is
+ preemption. To solve this problem, PulseAudio uses rtkit to safely
+ acquire real-time scheduling when available.</p>
+
+ <p>If the risk of locking up the machine is
considered too big to enable real-time scheduling, high-priority
scheduling can be enabled instead (i.e. negative nice level). This
can be enabled by passing <opt>--high-priority</opt> (see above)
diff --git a/meson.build b/meson.build
index a10a1b3..88394e4 100644
--- a/meson.build
+++ b/meson.build
@@ -23,7 +23,7 @@ pa_protocol_version = 33
# The stable ABI for client applications, for the version info x:y:z
# always will hold x=z
-libpulse_version_info = [21, 1, 21]
+libpulse_version_info = [21, 2, 21]
# A simplified, synchronous, ABI-stable interface for client
# applications, for the version info x:y:z always will hold x=z
@@ -296,6 +296,12 @@ if cc.has_function('SYS_memfd_create', prefix : '#include <sys/syscall.h>')
cdata.set('HAVE_MEMFD', 1)
endif
+if cc.has_function('dgettext')
+ libintl_dep = []
+else
+ libintl_dep = cc.find_library('intl')
+endif
+
# Symbols
if cc.has_header_symbol('signal.h', 'SIGXCPU')
@@ -663,6 +669,15 @@ if webrtc_dep.found()
cdata.set('HAVE_WEBRTC', 1)
endif
+gst_dep = dependency('gstreamer-1.0', required : get_option('gstreamer'))
+gstapp_dep = dependency('gstreamer-app-1.0', required : get_option('gstreamer'))
+gstrtp_dep = dependency('gstreamer-rtp-1.0', required : get_option('gstreamer'))
+
+have_gstreamer = false
+if gst_dep.found() and gstapp_dep.found() and gstrtp_dep.found()
+ have_gstreamer = true
+endif
+
# These are required for the CMake file generation
cdata.set('PA_LIBDIR', libdir)
cdata.set('PA_INCDIR', includedir)
@@ -809,6 +824,7 @@ summary = [
'Enable OpenSSL (for Airtunes): @0@'.format(openssl_dep.found()),
'Enable FFTW: @0@'.format(fftw_dep.found()),
'Enable ORC: @0@'.format(have_orcc),
+ 'Enable GStreamer: @0@'.format(have_gstreamer),
'Enable Adrian echo canceller: @0@'.format(get_option('adrian-aec')),
'Enable Speex (resampler, AEC): @0@'.format(speex_dep.found()),
'Enable SoXR (resampler): @0@'.format(soxr_dep.found()),
diff --git a/meson_options.txt b/meson_options.txt
index 7668773..8178892 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -56,10 +56,10 @@ option('udevrulesdir',
description : 'Directory for udev rules (defaults to /lib/udev/rules.d)')
option('bashcompletiondir',
type : 'string',
- description : 'Directory for bash completion files')
+ description : 'Directory for bash completion scripts ["no" disables]')
option('zshcompletiondir',
type : 'string',
- description : 'Zsh completions directory')
+ description : 'Directory for zsh completion scripts ["no" disables]')
# Optional features
@@ -93,6 +93,9 @@ option('glib',
option('gsettings',
type : 'feature', value : 'auto',
description : 'Optional GSettings support')
+option('gstreamer',
+ type : 'feature', value : 'auto',
+ description : 'Optional GStreamer dependency for media-related functionality')
option('gtk',
type : 'feature', value : 'auto',
description : 'Optional Gtk+ 3 support')
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0b51946..33f7ae3 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -66,7 +66,9 @@ src/modules/raop/raop-sink.c
src/modules/reserve-wrap.c
src/modules/rtp/module-rtp-recv.c
src/modules/rtp/module-rtp-send.c
-src/modules/rtp/rtp.c
+src/modules/rtp/rtp-common.c
+src/modules/rtp/rtp-native.c
+src/modules/rtp/rtp-gstreamer.c
src/modules/rtp/sap.c
src/modules/rtp/sdp.c
src/modules/x11/module-x11-bell.c
diff --git a/po/as.gmo b/po/as.gmo
index d493a4a..80c4746 100644
--- a/po/as.gmo
+++ b/po/as.gmo
Binary files differ
diff --git a/po/be.gmo b/po/be.gmo
index 88a8a2b..8cd7beb 100644
--- a/po/be.gmo
+++ b/po/be.gmo
Binary files differ
diff --git a/po/bn_IN.gmo b/po/bn_IN.gmo
index 6237262..342f119 100644
--- a/po/bn_IN.gmo
+++ b/po/bn_IN.gmo
Binary files differ
diff --git a/po/cs.gmo b/po/cs.gmo
index 2fafadf..d1e7553 100644
--- a/po/cs.gmo
+++ b/po/cs.gmo
Binary files differ
diff --git a/po/de.gmo b/po/de.gmo
index 1ba3f22..0d10da4 100644
--- a/po/de.gmo
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de_CH.gmo b/po/de_CH.gmo
index 808b012..75b3395 100644
--- a/po/de_CH.gmo
+++ b/po/de_CH.gmo
Binary files differ
diff --git a/po/el.gmo b/po/el.gmo
index c74bab5..428b4cc 100644
--- a/po/el.gmo
+++ b/po/el.gmo
Binary files differ
diff --git a/po/fi.gmo b/po/fi.gmo
index 5de29b2..d573724 100644
--- a/po/fi.gmo
+++ b/po/fi.gmo
Binary files differ
diff --git a/po/fr.gmo b/po/fr.gmo
index 9286b60..8efaf25 100644
--- a/po/fr.gmo
+++ b/po/fr.gmo
Binary files differ
diff --git a/po/gu.gmo b/po/gu.gmo
index 5915304..7541b3c 100644
--- a/po/gu.gmo
+++ b/po/gu.gmo
Binary files differ
diff --git a/po/he.gmo b/po/he.gmo
index 6f0a126..e7321cb 100644
--- a/po/he.gmo
+++ b/po/he.gmo
Binary files differ
diff --git a/po/hi.gmo b/po/hi.gmo
index 5524e1d..e10d251 100644
--- a/po/hi.gmo
+++ b/po/hi.gmo
Binary files differ
diff --git a/po/hr.gmo b/po/hr.gmo
index 6d30d3d..063f296 100644
--- a/po/hr.gmo
+++ b/po/hr.gmo
Binary files differ
diff --git a/po/hr.po b/po/hr.po
index cffcf8a..746d740 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: pulseaudio\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-06-23 13:50+0200\n"
-"PO-Revision-Date: 2019-06-23 14:20+0200\n"
+"POT-Creation-Date: 2019-11-10 14:12+0100\n"
+"PO-Revision-Date: 2019-11-10 14:21+0100\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <hr@li.org>\n"
"Language: hr\n"
@@ -578,165 +578,165 @@ msgid "Daemon startup without any loaded modules, refusing to work."
msgstr ""
"Pozadinski program je pokrenut bez ijednog učitanog modula, odbija raditi."
-#: ../src/modules/alsa/alsa-mixer.c:2443
+#: ../src/modules/alsa/alsa-mixer.c:2442
msgid "Input"
msgstr "Ulaz"
-#: ../src/modules/alsa/alsa-mixer.c:2444
+#: ../src/modules/alsa/alsa-mixer.c:2443
msgid "Docking Station Input"
msgstr "Ulaz priključne stanice"
-#: ../src/modules/alsa/alsa-mixer.c:2445
+#: ../src/modules/alsa/alsa-mixer.c:2444
msgid "Docking Station Microphone"
msgstr "Mikrofon priključne stanice"
-#: ../src/modules/alsa/alsa-mixer.c:2446
+#: ../src/modules/alsa/alsa-mixer.c:2445
msgid "Docking Station Line In"
msgstr "Ulaz priključne stanice"
-#: ../src/modules/alsa/alsa-mixer.c:2447 ../src/modules/alsa/alsa-mixer.c:2532
+#: ../src/modules/alsa/alsa-mixer.c:2446 ../src/modules/alsa/alsa-mixer.c:2531
msgid "Line In"
msgstr "Ulaz"
-#: ../src/modules/alsa/alsa-mixer.c:2448 ../src/modules/alsa/alsa-mixer.c:2526
-#: ../src/modules/bluetooth/module-bluez5-device.c:1709
+#: ../src/modules/alsa/alsa-mixer.c:2447 ../src/modules/alsa/alsa-mixer.c:2525
+#: ../src/modules/bluetooth/module-bluez5-device.c:1757
msgid "Microphone"
msgstr "Mikrofon"
-#: ../src/modules/alsa/alsa-mixer.c:2449 ../src/modules/alsa/alsa-mixer.c:2527
+#: ../src/modules/alsa/alsa-mixer.c:2448 ../src/modules/alsa/alsa-mixer.c:2526
msgid "Front Microphone"
msgstr "Prednji mikrofon"
-#: ../src/modules/alsa/alsa-mixer.c:2450 ../src/modules/alsa/alsa-mixer.c:2528
+#: ../src/modules/alsa/alsa-mixer.c:2449 ../src/modules/alsa/alsa-mixer.c:2527
msgid "Rear Microphone"
msgstr "Stražnji mikrofon"
-#: ../src/modules/alsa/alsa-mixer.c:2451
+#: ../src/modules/alsa/alsa-mixer.c:2450
msgid "External Microphone"
msgstr "Vanjski mikrofon"
-#: ../src/modules/alsa/alsa-mixer.c:2452 ../src/modules/alsa/alsa-mixer.c:2530
+#: ../src/modules/alsa/alsa-mixer.c:2451 ../src/modules/alsa/alsa-mixer.c:2529
msgid "Internal Microphone"
msgstr "Unutarnji mikrofon"
-#: ../src/modules/alsa/alsa-mixer.c:2453 ../src/modules/alsa/alsa-mixer.c:2533
+#: ../src/modules/alsa/alsa-mixer.c:2452 ../src/modules/alsa/alsa-mixer.c:2532
msgid "Radio"
msgstr "Radio"
-#: ../src/modules/alsa/alsa-mixer.c:2454 ../src/modules/alsa/alsa-mixer.c:2534
+#: ../src/modules/alsa/alsa-mixer.c:2453 ../src/modules/alsa/alsa-mixer.c:2533
msgid "Video"
msgstr "Video"
-#: ../src/modules/alsa/alsa-mixer.c:2455
+#: ../src/modules/alsa/alsa-mixer.c:2454
msgid "Automatic Gain Control"
msgstr "Automatska kontrola pojačanja"
-#: ../src/modules/alsa/alsa-mixer.c:2456
+#: ../src/modules/alsa/alsa-mixer.c:2455
msgid "No Automatic Gain Control"
msgstr "Bez automatske kontrole pojačanja"
-#: ../src/modules/alsa/alsa-mixer.c:2457
+#: ../src/modules/alsa/alsa-mixer.c:2456
msgid "Boost"
msgstr "Pojačanje"
-#: ../src/modules/alsa/alsa-mixer.c:2458
+#: ../src/modules/alsa/alsa-mixer.c:2457
msgid "No Boost"
msgstr "Bez pojačanja"
-#: ../src/modules/alsa/alsa-mixer.c:2459
+#: ../src/modules/alsa/alsa-mixer.c:2458
msgid "Amplifier"
msgstr "Pojačalo"
-#: ../src/modules/alsa/alsa-mixer.c:2460
+#: ../src/modules/alsa/alsa-mixer.c:2459
msgid "No Amplifier"
msgstr "Bez pojačala"
-#: ../src/modules/alsa/alsa-mixer.c:2461
+#: ../src/modules/alsa/alsa-mixer.c:2460
msgid "Bass Boost"
msgstr "Pojačanje basa"
-#: ../src/modules/alsa/alsa-mixer.c:2462
+#: ../src/modules/alsa/alsa-mixer.c:2461
msgid "No Bass Boost"
msgstr "Bez pojačanja basa"
-#: ../src/modules/alsa/alsa-mixer.c:2463
-#: ../src/modules/bluetooth/module-bluez5-device.c:1716
+#: ../src/modules/alsa/alsa-mixer.c:2462
+#: ../src/modules/bluetooth/module-bluez5-device.c:1764
msgid "Speaker"
msgstr "Zvučnik"
-#: ../src/modules/alsa/alsa-mixer.c:2464 ../src/modules/alsa/alsa-mixer.c:2536
+#: ../src/modules/alsa/alsa-mixer.c:2463 ../src/modules/alsa/alsa-mixer.c:2535
msgid "Headphones"
msgstr "Slušalice"
-#: ../src/modules/alsa/alsa-mixer.c:2525
+#: ../src/modules/alsa/alsa-mixer.c:2524
msgid "Analog Input"
msgstr "Analogni ulaz"
-#: ../src/modules/alsa/alsa-mixer.c:2529
+#: ../src/modules/alsa/alsa-mixer.c:2528
msgid "Dock Microphone"
msgstr "Ugrađeni mikrofon"
-#: ../src/modules/alsa/alsa-mixer.c:2531
+#: ../src/modules/alsa/alsa-mixer.c:2530
msgid "Headset Microphone"
msgstr "Mikrofon sa slušalicama"
-#: ../src/modules/alsa/alsa-mixer.c:2535
+#: ../src/modules/alsa/alsa-mixer.c:2534
msgid "Analog Output"
msgstr "Analogni izlaz"
-#: ../src/modules/alsa/alsa-mixer.c:2537
+#: ../src/modules/alsa/alsa-mixer.c:2536
msgid "Headphones Mono Output"
msgstr "Mono izlaz za slušalice"
-#: ../src/modules/alsa/alsa-mixer.c:2538
+#: ../src/modules/alsa/alsa-mixer.c:2537
msgid "LFE on Separate Mono Output"
msgstr "(LFE) Efekti niske frekvencije na odvojenom mono izlazu"
-#: ../src/modules/alsa/alsa-mixer.c:2539
+#: ../src/modules/alsa/alsa-mixer.c:2538
msgid "Line Out"
msgstr "Izlaz"
-#: ../src/modules/alsa/alsa-mixer.c:2540
+#: ../src/modules/alsa/alsa-mixer.c:2539
msgid "Analog Mono Output"
msgstr "Analogni mono izlaz"
-#: ../src/modules/alsa/alsa-mixer.c:2541
+#: ../src/modules/alsa/alsa-mixer.c:2540
msgid "Speakers"
msgstr "Zvučnici"
-#: ../src/modules/alsa/alsa-mixer.c:2542
+#: ../src/modules/alsa/alsa-mixer.c:2541
msgid "HDMI / DisplayPort"
msgstr "HDMI / DisplayPort"
-#: ../src/modules/alsa/alsa-mixer.c:2543
+#: ../src/modules/alsa/alsa-mixer.c:2542
msgid "Digital Output (S/PDIF)"
msgstr "Digitalni izlaz (S/PDIF)"
-#: ../src/modules/alsa/alsa-mixer.c:2544
+#: ../src/modules/alsa/alsa-mixer.c:2543
msgid "Digital Input (S/PDIF)"
msgstr "Digitalni ulaz (S/PDIF)"
-#: ../src/modules/alsa/alsa-mixer.c:2545
+#: ../src/modules/alsa/alsa-mixer.c:2544
msgid "Digital Passthrough (S/PDIF)"
msgstr "Digitalni prolaz (S/PDIF)"
-#: ../src/modules/alsa/alsa-mixer.c:2546
+#: ../src/modules/alsa/alsa-mixer.c:2545
msgid "Multichannel Input"
msgstr "Višekanalni ulaz"
-#: ../src/modules/alsa/alsa-mixer.c:2547
+#: ../src/modules/alsa/alsa-mixer.c:2546
msgid "Multichannel Output"
msgstr "Višekanalni izlaz"
-#: ../src/modules/alsa/alsa-mixer.c:2548
+#: ../src/modules/alsa/alsa-mixer.c:2547
msgid "Game Output"
msgstr "Izlaz za igre"
-#: ../src/modules/alsa/alsa-mixer.c:2549
+#: ../src/modules/alsa/alsa-mixer.c:2548
msgid "Chat Output"
msgstr "Izlaz razgovora"
-#: ../src/modules/alsa/alsa-mixer.c:4063
+#: ../src/modules/alsa/alsa-mixer.c:4062
msgid "Analog Mono"
msgstr "Analogni mono"
@@ -745,128 +745,128 @@ msgstr "Analogni mono"
#. * here would lead to the source name to become "Analog Stereo Input
#. * Input". The same logic applies to analog-stereo-output,
#. * multichannel-input and multichannel-output.
-#: ../src/modules/alsa/alsa-mixer.c:4064 ../src/modules/alsa/alsa-mixer.c:4072
-#: ../src/modules/alsa/alsa-mixer.c:4073
+#: ../src/modules/alsa/alsa-mixer.c:4063 ../src/modules/alsa/alsa-mixer.c:4071
+#: ../src/modules/alsa/alsa-mixer.c:4072
msgid "Analog Stereo"
msgstr "Analogni stereo"
-#: ../src/modules/alsa/alsa-mixer.c:4065 ../src/pulse/channelmap.c:103
+#: ../src/modules/alsa/alsa-mixer.c:4064 ../src/pulse/channelmap.c:103
#: ../src/pulse/channelmap.c:771
msgid "Mono"
msgstr "Mono"
-#: ../src/modules/alsa/alsa-mixer.c:4066 ../src/pulse/channelmap.c:775
+#: ../src/modules/alsa/alsa-mixer.c:4065 ../src/pulse/channelmap.c:775
msgid "Stereo"
msgstr "Stereo"
-#: ../src/modules/alsa/alsa-mixer.c:4074 ../src/modules/alsa/alsa-mixer.c:4075
+#: ../src/modules/alsa/alsa-mixer.c:4073 ../src/modules/alsa/alsa-mixer.c:4074
msgid "Multichannel"
msgstr "Višekanalni"
-#: ../src/modules/alsa/alsa-mixer.c:4076
+#: ../src/modules/alsa/alsa-mixer.c:4075
msgid "Analog Surround 2.1"
msgstr "Analogni surround 2.1"
-#: ../src/modules/alsa/alsa-mixer.c:4077
+#: ../src/modules/alsa/alsa-mixer.c:4076
msgid "Analog Surround 3.0"
msgstr "Analogni surround 3.0"
-#: ../src/modules/alsa/alsa-mixer.c:4078
+#: ../src/modules/alsa/alsa-mixer.c:4077
msgid "Analog Surround 3.1"
msgstr "Analogni surround 3.1"
-#: ../src/modules/alsa/alsa-mixer.c:4079
+#: ../src/modules/alsa/alsa-mixer.c:4078
msgid "Analog Surround 4.0"
msgstr "Analogni surround 4.0"
-#: ../src/modules/alsa/alsa-mixer.c:4080
+#: ../src/modules/alsa/alsa-mixer.c:4079
msgid "Analog Surround 4.1"
msgstr "Analogni surround 4.1"
-#: ../src/modules/alsa/alsa-mixer.c:4081
+#: ../src/modules/alsa/alsa-mixer.c:4080
msgid "Analog Surround 5.0"
msgstr "Analogni surround 5.0"
-#: ../src/modules/alsa/alsa-mixer.c:4082
+#: ../src/modules/alsa/alsa-mixer.c:4081
msgid "Analog Surround 5.1"
msgstr "Analogni surround 5.1"
-#: ../src/modules/alsa/alsa-mixer.c:4083
+#: ../src/modules/alsa/alsa-mixer.c:4082
msgid "Analog Surround 6.0"
msgstr "Analogni surround 6.0"
-#: ../src/modules/alsa/alsa-mixer.c:4084
+#: ../src/modules/alsa/alsa-mixer.c:4083
msgid "Analog Surround 6.1"
msgstr "Analogni surround 6.1"
-#: ../src/modules/alsa/alsa-mixer.c:4085
+#: ../src/modules/alsa/alsa-mixer.c:4084
msgid "Analog Surround 7.0"
msgstr "Analogni surround 7.0"
-#: ../src/modules/alsa/alsa-mixer.c:4086
+#: ../src/modules/alsa/alsa-mixer.c:4085
msgid "Analog Surround 7.1"
msgstr "Analogni surround 7.1"
-#: ../src/modules/alsa/alsa-mixer.c:4087
+#: ../src/modules/alsa/alsa-mixer.c:4086
msgid "Digital Stereo (IEC958)"
msgstr "Digitalni stereo (IEC958)"
-#: ../src/modules/alsa/alsa-mixer.c:4088
+#: ../src/modules/alsa/alsa-mixer.c:4087
msgid "Digital Passthrough (IEC958)"
msgstr "Digitalni prolaz (IEC958)"
-#: ../src/modules/alsa/alsa-mixer.c:4089
+#: ../src/modules/alsa/alsa-mixer.c:4088
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "Digitalni surround 4.0 (IEC958/AC3)"
-#: ../src/modules/alsa/alsa-mixer.c:4090
+#: ../src/modules/alsa/alsa-mixer.c:4089
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "Digitalni surround 5.1 (IEC958/AC3)"
-#: ../src/modules/alsa/alsa-mixer.c:4091
+#: ../src/modules/alsa/alsa-mixer.c:4090
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "Digitalni surround 5.1 (IEC958/DTS)"
-#: ../src/modules/alsa/alsa-mixer.c:4092
+#: ../src/modules/alsa/alsa-mixer.c:4091
msgid "Digital Stereo (HDMI)"
msgstr "Digitalni stereo (HDMI)"
-#: ../src/modules/alsa/alsa-mixer.c:4093
+#: ../src/modules/alsa/alsa-mixer.c:4092
msgid "Digital Surround 5.1 (HDMI)"
msgstr "Digitalni surround 5.1 (HDMI)"
-#: ../src/modules/alsa/alsa-mixer.c:4226
+#: ../src/modules/alsa/alsa-mixer.c:4225
msgid "Analog Mono Duplex"
msgstr "Analogni mono obostrani"
-#: ../src/modules/alsa/alsa-mixer.c:4227
+#: ../src/modules/alsa/alsa-mixer.c:4226
msgid "Analog Stereo Duplex"
msgstr "Analogni stereo obostrani"
-#: ../src/modules/alsa/alsa-mixer.c:4228
+#: ../src/modules/alsa/alsa-mixer.c:4227
msgid "Digital Stereo Duplex (IEC958)"
msgstr "Digitalni stereo obostrani (IEC958)"
-#: ../src/modules/alsa/alsa-mixer.c:4229
+#: ../src/modules/alsa/alsa-mixer.c:4228
msgid "Multichannel Duplex"
msgstr "Višekanalni obostrani"
-#: ../src/modules/alsa/alsa-mixer.c:4230
+#: ../src/modules/alsa/alsa-mixer.c:4229
msgid "Stereo Duplex"
msgstr "Stereo obostrani"
-#: ../src/modules/alsa/alsa-mixer.c:4231
+#: ../src/modules/alsa/alsa-mixer.c:4230
#: ../src/modules/alsa/module-alsa-card.c:189
-#: ../src/modules/bluetooth/module-bluez5-device.c:1964
+#: ../src/modules/bluetooth/module-bluez5-device.c:2012
msgid "Off"
msgstr "Isključeno"
-#: ../src/modules/alsa/alsa-mixer.c:4330
+#: ../src/modules/alsa/alsa-mixer.c:4329
#, c-format
msgid "%s Output"
msgstr "%s izlaz"
-#: ../src/modules/alsa/alsa-mixer.c:4338
+#: ../src/modules/alsa/alsa-mixer.c:4337
#, c-format
msgid "%s Input"
msgstr "%s ulaz"
@@ -1002,60 +1002,60 @@ msgstr[2] ""
"Najvjerojatnije je ovo greška ALSA upravljačkog programa '%s'. Prijavite "
"problem ALSA razvijateljima."
-#: ../src/modules/bluetooth/module-bluez5-device.c:1693
-#: ../src/modules/bluetooth/module-bluez5-device.c:1715
-#: ../src/modules/bluetooth/module-bluez5-device.c:1721
-#: ../src/modules/bluetooth/module-bluez5-device.c:1747
+#: ../src/modules/bluetooth/module-bluez5-device.c:1741
+#: ../src/modules/bluetooth/module-bluez5-device.c:1763
+#: ../src/modules/bluetooth/module-bluez5-device.c:1769
+#: ../src/modules/bluetooth/module-bluez5-device.c:1795
msgid "Bluetooth Input"
msgstr "Bluetooth ulaz"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1694
-#: ../src/modules/bluetooth/module-bluez5-device.c:1710
-#: ../src/modules/bluetooth/module-bluez5-device.c:1748
+#: ../src/modules/bluetooth/module-bluez5-device.c:1742
+#: ../src/modules/bluetooth/module-bluez5-device.c:1758
+#: ../src/modules/bluetooth/module-bluez5-device.c:1796
msgid "Bluetooth Output"
msgstr "Bluetooth izlaz"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1699
+#: ../src/modules/bluetooth/module-bluez5-device.c:1747
msgid "Headset"
msgstr "Slušalice s mikrofonom"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1704
+#: ../src/modules/bluetooth/module-bluez5-device.c:1752
msgid "Handsfree"
msgstr "Bez-ruku"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1722
+#: ../src/modules/bluetooth/module-bluez5-device.c:1770
msgid "Headphone"
msgstr "Slušalice"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1727
+#: ../src/modules/bluetooth/module-bluez5-device.c:1775
msgid "Portable"
msgstr "Prijenosnik"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1732
+#: ../src/modules/bluetooth/module-bluez5-device.c:1780
msgid "Car"
msgstr "Automobil"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1737
+#: ../src/modules/bluetooth/module-bluez5-device.c:1785
msgid "HiFi"
msgstr "HiFi"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1742
+#: ../src/modules/bluetooth/module-bluez5-device.c:1790
msgid "Phone"
msgstr "Telefon"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1789
+#: ../src/modules/bluetooth/module-bluez5-device.c:1837
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Reprodukcija visoke autentičnosti (A2DP slivnik)"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1801
+#: ../src/modules/bluetooth/module-bluez5-device.c:1849
msgid "High Fidelity Capture (A2DP Source)"
msgstr "Snimanje visoke autentičnosti (A2DP izvor)"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1813
+#: ../src/modules/bluetooth/module-bluez5-device.c:1861
msgid "Headset Head Unit (HSP/HFP)"
msgstr "Jedinica slušalice s mikrofonom (HSP/HFP)"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1826
+#: ../src/modules/bluetooth/module-bluez5-device.c:1874
msgid "Headset Audio Gateway (HSP/HFP)"
msgstr "Zvučni pristupnik slušalice s mikrofonom (HSP/HFP)"
@@ -1221,7 +1221,7 @@ msgstr ""
msgid "Unknown device model"
msgstr "Nepoznat model uređaja"
-#: ../src/modules/raop/raop-sink.c:507
+#: ../src/modules/raop/raop-sink.c:511
msgid "RAOP standard profile"
msgstr "RAOP standardan profil"
@@ -1457,29 +1457,29 @@ msgstr "Surround 5.1"
msgid "Surround 7.1"
msgstr "Surround 7.1"
-#: ../src/pulse/client-conf-x11.c:53 ../src/utils/pax11publish.c:97
+#: ../src/pulse/client-conf-x11.c:61 ../src/utils/pax11publish.c:97
msgid "xcb_connect() failed"
msgstr "xcb_connect() neuspjelo"
-#: ../src/pulse/client-conf-x11.c:58 ../src/utils/pax11publish.c:102
+#: ../src/pulse/client-conf-x11.c:66 ../src/utils/pax11publish.c:102
msgid "xcb_connection_has_error() returned true"
msgstr "xcb_connection_has_error() vratilo je 'true'"
-#: ../src/pulse/client-conf-x11.c:94
+#: ../src/pulse/client-conf-x11.c:102
msgid "Failed to parse cookie data"
msgstr "Neuspjela obrada podataka kolačića"
-#: ../src/pulse/context.c:705
+#: ../src/pulse/context.c:706
#, c-format
msgid "fork(): %s"
msgstr "fork(): %s"
-#: ../src/pulse/context.c:760
+#: ../src/pulse/context.c:761
#, c-format
msgid "waitpid(): %s"
msgstr "waitpid(): %s"
-#: ../src/pulse/context.c:1466
+#: ../src/pulse/context.c:1467
#, c-format
msgid "Received message for unknown extension '%s'"
msgstr "Primljena poruka za nepoznato proširenje '%s'"
@@ -3125,7 +3125,9 @@ msgstr "WARNING: podređeni proces je završen sa signalom %u\n"
#: ../src/utils/pasuspender.c:228
#, c-format
msgid ""
-"%s [options] ... \n"
+"%s [options] -- PROGRAM [ARGUMENTS ...]\n"
+"\n"
+"Temporarily suspend PulseAudio while PROGRAM runs.\n"
"\n"
" -h, --help Show this help\n"
" --version Show version\n"
@@ -3133,14 +3135,16 @@ msgid ""
"to\n"
"\n"
msgstr ""
-"%s [mogućnosti] ... \n"
+"%s [mogućnosti] -- PROGRAM [ARGUMENTI ...]\n"
+"\n"
+"Privremeno suspendira PulseAudio dok je PROGRAM pokrenut.\n"
"\n"
" -h, --help Prikazuje ovu pomoć\n"
" --version Prikazuje inačicu\n"
" -s, --server=SERVER Naziv poslužitelja za povezivanje\n"
"\n"
-#: ../src/utils/pasuspender.c:266
+#: ../src/utils/pasuspender.c:267
#, c-format
msgid ""
"pasuspender %s\n"
@@ -3151,17 +3155,17 @@ msgstr ""
"Kompilirano s libpulse %s\n"
"Povezano s libpulse %s\n"
-#: ../src/utils/pasuspender.c:295
+#: ../src/utils/pasuspender.c:296
#, c-format
msgid "pa_mainloop_new() failed.\n"
msgstr "pa_mainloop_new() neuspjelo.\n"
-#: ../src/utils/pasuspender.c:308
+#: ../src/utils/pasuspender.c:309
#, c-format
msgid "pa_context_new() failed.\n"
msgstr "pa_context_new() neuspjelo.\n"
-#: ../src/utils/pasuspender.c:320
+#: ../src/utils/pasuspender.c:321
#, c-format
msgid "pa_mainloop_run() failed.\n"
msgstr "pa_mainloop_run() neuspjelo.\n"
diff --git a/po/hu.gmo b/po/hu.gmo
index 2db4518..ead5ff6 100644
--- a/po/hu.gmo
+++ b/po/hu.gmo
Binary files differ
diff --git a/po/id.gmo b/po/id.gmo
index d5abf3d..c887ecf 100644
--- a/po/id.gmo
+++ b/po/id.gmo
Binary files differ
diff --git a/po/it.gmo b/po/it.gmo
index a9aa653..a4c9974 100644
--- a/po/it.gmo
+++ b/po/it.gmo
Binary files differ
diff --git a/po/it.po b/po/it.po
index dcb185a..33cece3 100644
--- a/po/it.po
+++ b/po/it.po
@@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: pulseaudio\n"
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/"
"issues\n"
-"POT-Creation-Date: 2019-02-16 11:57+0000\n"
-"PO-Revision-Date: 2019-08-07 09:53+0200\n"
+"POT-Creation-Date: 2019-09-17 03:33+0000\n"
+"PO-Revision-Date: 2019-09-19 09:56+0200\n"
"Last-Translator: Milo Casagrande <milo@milo.name>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"Language: it\n"
@@ -582,11 +582,20 @@ msgstr "pa_pid_file_create() non riuscita."
msgid "pa_core_new() failed."
msgstr "pa_core_new() non riuscita."
-#: src/daemon/main.c:1109
-msgid "Failed to initialize daemon."
-msgstr "Inizializzazione del demone non riuscita."
+#: src/daemon/main.c:1108
+msgid "command line arguments"
+msgstr "argomenti della riga di comando"
-#: src/daemon/main.c:1114
+#: src/daemon/main.c:1115
+#, c-format
+msgid ""
+"Failed to initialize daemon due to errors while executing startup commands. "
+"Source of commands: %s"
+msgstr ""
+"Inizializzazione del demone non riuscita a causa di errori nell'eseguire i "
+"comandi di avvio. Origine dei comandi: %s"
+
+#: src/daemon/main.c:1120
msgid "Daemon startup without any loaded modules, refusing to work."
msgstr "Avvio del demone senza alcun modulo caricato, rifiuta di lavorare."
@@ -619,7 +628,7 @@ msgid "Line In"
msgstr "Line-In"
#: src/modules/alsa/alsa-mixer.c:2448 src/modules/alsa/alsa-mixer.c:2526
-#: src/modules/bluetooth/module-bluez5-device.c:1909
+#: src/modules/bluetooth/module-bluez5-device.c:1757
msgid "Microphone"
msgstr "Microfono"
@@ -680,7 +689,7 @@ msgid "No Bass Boost"
msgstr "Nessun incremento bassi"
#: src/modules/alsa/alsa-mixer.c:2463
-#: src/modules/bluetooth/module-bluez5-device.c:1916
+#: src/modules/bluetooth/module-bluez5-device.c:1764
msgid "Speaker"
msgstr "Altoparlante"
@@ -875,8 +884,8 @@ msgstr "Duplex multi canale"
msgid "Stereo Duplex"
msgstr "Duplex stereo"
-#: src/modules/alsa/alsa-mixer.c:4231 src/modules/alsa/module-alsa-card.c:187
-#: src/modules/bluetooth/module-bluez5-device.c:2164
+#: src/modules/alsa/alsa-mixer.c:4231 src/modules/alsa/module-alsa-card.c:189
+#: src/modules/bluetooth/module-bluez5-device.c:2012
msgid "Off"
msgstr "Spento"
@@ -890,7 +899,7 @@ msgstr "Uscita «%s»"
msgid "%s Input"
msgstr "Ingresso «%s»"
-#: src/modules/alsa/alsa-sink.c:587 src/modules/alsa/alsa-sink.c:771
+#: src/modules/alsa/alsa-sink.c:651 src/modules/alsa/alsa-sink.c:841
#, c-format
msgid ""
"ALSA woke us up to write new data to the device, but there was actually "
@@ -907,7 +916,7 @@ msgstr ""
"Attivazione avvenuta con POLLOUT impostato; tuttavia, una successiva "
"snd_pcm_avail() ha ritornato 0 o un altro valore < min_avail."
-#: src/modules/alsa/alsa-source.c:543 src/modules/alsa/alsa-source.c:694
+#: src/modules/alsa/alsa-source.c:610 src/modules/alsa/alsa-source.c:776
#, c-format
msgid ""
"ALSA woke us up to read new data from the device, but there was actually "
@@ -924,7 +933,7 @@ msgstr ""
"Attivazione avvenuta con POLLIN impostato; tuttavia, una successiva "
"snd_pcm_avail() ha ritornato 0 o un altro valore < min_avail."
-#: src/modules/alsa/alsa-util.c:1168 src/modules/alsa/alsa-util.c:1262
+#: src/modules/alsa/alsa-util.c:1173 src/modules/alsa/alsa-util.c:1267
#, c-format
msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
@@ -945,7 +954,7 @@ msgstr[1] ""
"Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
"questo problema agli sviluppatori ALSA."
-#: src/modules/alsa/alsa-util.c:1234
+#: src/modules/alsa/alsa-util.c:1239
#, c-format
msgid ""
"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
@@ -966,7 +975,7 @@ msgstr[1] ""
"Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
"questo problema agli sviluppatori ALSA."
-#: src/modules/alsa/alsa-util.c:1281
+#: src/modules/alsa/alsa-util.c:1286
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
@@ -979,7 +988,7 @@ msgstr ""
"Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
"questo problema agli sviluppatori ALSA."
-#: src/modules/alsa/alsa-util.c:1324
+#: src/modules/alsa/alsa-util.c:1329
#, c-format
msgid ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
@@ -1002,60 +1011,60 @@ msgstr[1] ""
"Molto probabilmente si tratta di un bug nel driver ALSA «%s». Segnalare "
"questo problema agli sviluppatori ALSA."
-#: src/modules/bluetooth/module-bluez5-device.c:1893
-#: src/modules/bluetooth/module-bluez5-device.c:1915
-#: src/modules/bluetooth/module-bluez5-device.c:1921
-#: src/modules/bluetooth/module-bluez5-device.c:1947
+#: src/modules/bluetooth/module-bluez5-device.c:1741
+#: src/modules/bluetooth/module-bluez5-device.c:1763
+#: src/modules/bluetooth/module-bluez5-device.c:1769
+#: src/modules/bluetooth/module-bluez5-device.c:1795
msgid "Bluetooth Input"
msgstr "Ingresso Bluetooth"
-#: src/modules/bluetooth/module-bluez5-device.c:1894
-#: src/modules/bluetooth/module-bluez5-device.c:1910
-#: src/modules/bluetooth/module-bluez5-device.c:1948
+#: src/modules/bluetooth/module-bluez5-device.c:1742
+#: src/modules/bluetooth/module-bluez5-device.c:1758
+#: src/modules/bluetooth/module-bluez5-device.c:1796
msgid "Bluetooth Output"
msgstr "Uscita Bluetooth"
-#: src/modules/bluetooth/module-bluez5-device.c:1899
+#: src/modules/bluetooth/module-bluez5-device.c:1747
msgid "Headset"
msgstr "Cuffie con microfono"
-#: src/modules/bluetooth/module-bluez5-device.c:1904
+#: src/modules/bluetooth/module-bluez5-device.c:1752
msgid "Handsfree"
msgstr "Sistema mani-libere"
-#: src/modules/bluetooth/module-bluez5-device.c:1922
+#: src/modules/bluetooth/module-bluez5-device.c:1770
msgid "Headphone"
msgstr "Cuffie"
-#: src/modules/bluetooth/module-bluez5-device.c:1927
+#: src/modules/bluetooth/module-bluez5-device.c:1775
msgid "Portable"
msgstr "Portabile"
-#: src/modules/bluetooth/module-bluez5-device.c:1932
+#: src/modules/bluetooth/module-bluez5-device.c:1780
msgid "Car"
msgstr "Automobile"
-#: src/modules/bluetooth/module-bluez5-device.c:1937
+#: src/modules/bluetooth/module-bluez5-device.c:1785
msgid "HiFi"
msgstr "HiFi"
-#: src/modules/bluetooth/module-bluez5-device.c:1942
+#: src/modules/bluetooth/module-bluez5-device.c:1790
msgid "Phone"
msgstr "Telefono"
-#: src/modules/bluetooth/module-bluez5-device.c:1989
+#: src/modules/bluetooth/module-bluez5-device.c:1837
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "Riproduzione ad alta fedeltà (sink A2DP)"
-#: src/modules/bluetooth/module-bluez5-device.c:2001
+#: src/modules/bluetooth/module-bluez5-device.c:1849
msgid "High Fidelity Capture (A2DP Source)"
msgstr "Registrazione ad alta fedeltà (sorgente A2DP)"
-#: src/modules/bluetooth/module-bluez5-device.c:2013
+#: src/modules/bluetooth/module-bluez5-device.c:1861
msgid "Headset Head Unit (HSP/HFP)"
msgstr "Unità headset head (HSP/HFP)"
-#: src/modules/bluetooth/module-bluez5-device.c:2026
+#: src/modules/bluetooth/module-bluez5-device.c:1874
msgid "Headset Audio Gateway (HSP/HFP)"
msgstr "Gateway headset audio (HSP/HFP)"
@@ -1158,11 +1167,11 @@ msgstr ""
msgid "Clocked NULL sink"
msgstr "Sink NULL temporizzato"
-#: src/modules/module-null-sink.c:322
+#: src/modules/module-null-sink.c:333
msgid "Null Output"
msgstr "Uscita nulla"
-#: src/modules/module-null-sink.c:334 src/utils/pactl.c:1058
+#: src/modules/module-null-sink.c:345 src/utils/pactl.c:1058
#, c-format
msgid "Failed to set format: invalid format string %s"
msgstr "Impostazione del formato non riuscita: stringa %s non valida"
@@ -1222,7 +1231,7 @@ msgstr ""
msgid "Unknown device model"
msgstr "Modello dispositivo sconosciuto"
-#: src/modules/raop/raop-sink.c:507
+#: src/modules/raop/raop-sink.c:511
msgid "RAOP standard profile"
msgstr "Profilo standard RAOP"
@@ -1458,15 +1467,15 @@ msgstr "Surround 5.1"
msgid "Surround 7.1"
msgstr "Surround 7.1"
-#: src/pulse/client-conf-x11.c:53 src/utils/pax11publish.c:97
+#: src/pulse/client-conf-x11.c:61 src/utils/pax11publish.c:97
msgid "xcb_connect() failed"
msgstr "xcb_connect() non riuscita"
-#: src/pulse/client-conf-x11.c:58 src/utils/pax11publish.c:102
+#: src/pulse/client-conf-x11.c:66 src/utils/pax11publish.c:102
msgid "xcb_connection_has_error() returned true"
msgstr "xcb_connection_has_error() ha restituito VERO"
-#: src/pulse/client-conf-x11.c:94
+#: src/pulse/client-conf-x11.c:102
msgid "Failed to parse cookie data"
msgstr "Analisi dei dati cookie non riuscita"
@@ -1542,11 +1551,11 @@ msgstr ""
msgid "Invalid log target."
msgstr "Destinazione di registrazione non valida."
-#: src/pulsecore/sink.c:3507
+#: src/pulsecore/sink.c:3516
msgid "Built-in Audio"
msgstr "Audio interno"
-#: src/pulsecore/sink.c:3512
+#: src/pulsecore/sink.c:3521
msgid "Modem"
msgstr "Modem"
@@ -3155,7 +3164,9 @@ msgstr "ATTENZIONE: processo figlio terminato dal segnale %u\n"
#: src/utils/pasuspender.c:228
#, c-format
msgid ""
-"%s [options] ... \n"
+"%s [options] -- PROGRAM [ARGUMENTS ...]\n"
+"\n"
+"Temporarily suspend PulseAudio while PROGRAM runs.\n"
"\n"
" -h, --help Show this help\n"
" --version Show version\n"
@@ -3163,7 +3174,9 @@ msgid ""
"to\n"
"\n"
msgstr ""
-"%s [OPZIONI] ... \n"
+"%s [OPZIONI] -- PROGRAMMA [ARGOMENTI ...] \n"
+"\n"
+"Sospende temporaneamente PulseAudio mentre PROGRAMMA è in esecuzione.\n"
"\n"
" -h, --help Mostra questo aiuto\n"
" --version Mostra la versione\n"
@@ -3171,7 +3184,7 @@ msgstr ""
"connettersi\n"
"\n"
-#: src/utils/pasuspender.c:266
+#: src/utils/pasuspender.c:267
#, c-format
msgid ""
"pasuspender %s\n"
@@ -3182,17 +3195,17 @@ msgstr ""
"Compilato con libpulse %s\n"
"Link eseguito con libpulse %s\n"
-#: src/utils/pasuspender.c:295
+#: src/utils/pasuspender.c:296
#, c-format
msgid "pa_mainloop_new() failed.\n"
msgstr "pa_mainloop_new() non riuscita.\n"
-#: src/utils/pasuspender.c:308
+#: src/utils/pasuspender.c:309
#, c-format
msgid "pa_context_new() failed.\n"
msgstr "pa_context_new() non riuscita.\n"
-#: src/utils/pasuspender.c:320
+#: src/utils/pasuspender.c:321
#, c-format
msgid "pa_mainloop_run() failed.\n"
msgstr "pa_mainloop_run() non riuscita.\n"
diff --git a/po/ja.gmo b/po/ja.gmo
index 4066e63..a790bfc 100644
--- a/po/ja.gmo
+++ b/po/ja.gmo
Binary files differ
diff --git a/po/kn.gmo b/po/kn.gmo
index f07e57f..fd58791 100644
--- a/po/kn.gmo
+++ b/po/kn.gmo
Binary files differ
diff --git a/po/ko.gmo b/po/ko.gmo
index 5ed863e..82774c9 100644
--- a/po/ko.gmo
+++ b/po/ko.gmo
Binary files differ
diff --git a/po/mr.gmo b/po/mr.gmo
index 310e9b3..861c888 100644
--- a/po/mr.gmo
+++ b/po/mr.gmo
Binary files differ
diff --git a/po/nl.gmo b/po/nl.gmo
index 8e0d50e..a73f2eb 100644
--- a/po/nl.gmo
+++ b/po/nl.gmo
Binary files differ
diff --git a/po/nn.gmo b/po/nn.gmo
index 11b40ee..7476877 100644
--- a/po/nn.gmo
+++ b/po/nn.gmo
Binary files differ
diff --git a/po/oc.gmo b/po/oc.gmo
index 974b370..24e4d6a 100644
--- a/po/oc.gmo
+++ b/po/oc.gmo
Binary files differ
diff --git a/po/or.gmo b/po/or.gmo
index e191436..1007431 100644
--- a/po/or.gmo
+++ b/po/or.gmo
Binary files differ
diff --git a/po/pa.gmo b/po/pa.gmo
index 4911296..38ce8d9 100644
--- a/po/pa.gmo
+++ b/po/pa.gmo
Binary files differ
diff --git a/po/pt.gmo b/po/pt.gmo
index 89dfcb7..6c1f79b 100644
--- a/po/pt.gmo
+++ b/po/pt.gmo
Binary files differ
diff --git a/po/pulseaudio.pot b/po/pulseaudio.pot
index 94633a8..a9f83a2 100644
--- a/po/pulseaudio.pot
+++ b/po/pulseaudio.pot
@@ -6,10 +6,10 @@
#, fuzzy
msgid ""
msgstr ""
-"Project-Id-Version: pulseaudio 13.0\n"
+"Project-Id-Version: pulseaudio 12.0-107-g8fdd8\n"
"Report-Msgid-Bugs-To: pulseaudio-discuss (at) lists (dot) freedesktop (dot) "
"org\n"
-"POT-Creation-Date: 2019-09-13 16:22+0300\n"
+"POT-Creation-Date: 2018-08-23 07:45+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,7 +17,6 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: src/daemon/cmdline.c:113
#, c-format
@@ -50,7 +49,8 @@ msgid ""
" (only available as root, when SUID "
"or\n"
" with elevated RLIMIT_RTPRIO)\n"
-" --disallow-module-loading[=BOOL] Disallow 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 "
@@ -127,7 +127,7 @@ msgstr ""
#: src/daemon/cmdline.c:328
msgid ""
-"Invalid log target: use either 'syslog', 'journal', 'stderr' or 'auto' or a "
+"Invalid log target: use either 'syslog', 'journal','stderr' or 'auto' or a "
"valid file name 'file:<path>', 'newfile:<path>'."
msgstr ""
@@ -166,78 +166,78 @@ msgstr ""
msgid "--enable-memfd expects boolean argument"
msgstr ""
-#: src/daemon/daemon-conf.c:268
+#: src/daemon/daemon-conf.c:266
#, c-format
msgid "[%s:%u] Invalid log target '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:283
+#: src/daemon/daemon-conf.c:281
#, c-format
msgid "[%s:%u] Invalid log level '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:298
+#: src/daemon/daemon-conf.c:296
#, c-format
msgid "[%s:%u] Invalid resample method '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:320
+#: src/daemon/daemon-conf.c:318
#, c-format
msgid "[%s:%u] Invalid rlimit '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:340
+#: src/daemon/daemon-conf.c:338
#, c-format
msgid "[%s:%u] Invalid sample format '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:357 src/daemon/daemon-conf.c:374
+#: src/daemon/daemon-conf.c:355 src/daemon/daemon-conf.c:372
#, c-format
msgid "[%s:%u] Invalid sample rate '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:397
+#: src/daemon/daemon-conf.c:395
#, c-format
msgid "[%s:%u] Invalid sample channels '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:414
+#: src/daemon/daemon-conf.c:412
#, c-format
msgid "[%s:%u] Invalid channel map '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:431
+#: src/daemon/daemon-conf.c:429
#, c-format
msgid "[%s:%u] Invalid number of fragments '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:448
+#: src/daemon/daemon-conf.c:446
#, c-format
msgid "[%s:%u] Invalid fragment size '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:465
+#: src/daemon/daemon-conf.c:463
#, c-format
msgid "[%s:%u] Invalid nice level '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:508
+#: src/daemon/daemon-conf.c:506
#, c-format
msgid "[%s:%u] Invalid server type '%s'."
msgstr ""
-#: src/daemon/daemon-conf.c:626
+#: src/daemon/daemon-conf.c:624
#, c-format
msgid "Failed to open configuration file: %s"
msgstr ""
-#: src/daemon/daemon-conf.c:642
+#: src/daemon/daemon-conf.c:640
msgid ""
"The specified default channel map has a different number of channels than "
"the specified default number of channels."
msgstr ""
-#: src/daemon/daemon-conf.c:729
+#: src/daemon/daemon-conf.c:727
#, c-format
msgid "### Read from configuration file: %s ###\n"
msgstr ""
@@ -432,11 +432,11 @@ msgstr ""
msgid "setsid() failed: %s"
msgstr ""
-#: src/daemon/main.c:965
+#: src/daemon/main.c:959
msgid "Failed to get machine ID"
msgstr ""
-#: src/daemon/main.c:991
+#: src/daemon/main.c:985
msgid ""
"OK, so you are running PA in system mode. Please make sure that you actually "
"do want to do that.\n"
@@ -445,26 +445,19 @@ msgid ""
"mode is usually a bad idea."
msgstr ""
-#: src/daemon/main.c:1007
+#: src/daemon/main.c:1001
msgid "pa_pid_file_create() failed."
msgstr ""
-#: src/daemon/main.c:1039
+#: src/daemon/main.c:1033
msgid "pa_core_new() failed."
msgstr ""
-#: src/daemon/main.c:1108
-msgid "command line arguments"
-msgstr ""
-
-#: src/daemon/main.c:1115
-#, c-format
-msgid ""
-"Failed to initialize daemon due to errors while executing startup commands. "
-"Source of commands: %s"
+#: src/daemon/main.c:1103
+msgid "Failed to initialize daemon."
msgstr ""
-#: src/daemon/main.c:1120
+#: src/daemon/main.c:1108
msgid "Daemon startup without any loaded modules, refusing to work."
msgstr ""
@@ -497,7 +490,7 @@ msgid "Line In"
msgstr ""
#: src/modules/alsa/alsa-mixer.c:2448 src/modules/alsa/alsa-mixer.c:2526
-#: src/modules/bluetooth/module-bluez5-device.c:1757
+#: src/modules/bluetooth/module-bluez5-device.c:1904
msgid "Microphone"
msgstr ""
@@ -558,7 +551,7 @@ msgid "No Bass Boost"
msgstr ""
#: src/modules/alsa/alsa-mixer.c:2463
-#: src/modules/bluetooth/module-bluez5-device.c:1764
+#: src/modules/bluetooth/module-bluez5-device.c:1911
msgid "Speaker"
msgstr ""
@@ -634,136 +627,136 @@ msgstr ""
msgid "Chat Output"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4063
+#: src/modules/alsa/alsa-mixer.c:4061
msgid "Analog Mono"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4064 src/modules/alsa/alsa-mixer.c:4072
-#: src/modules/alsa/alsa-mixer.c:4073
+#: src/modules/alsa/alsa-mixer.c:4062 src/modules/alsa/alsa-mixer.c:4070
+#: src/modules/alsa/alsa-mixer.c:4071
msgid "Analog Stereo"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4065 src/pulse/channelmap.c:103
+#: src/modules/alsa/alsa-mixer.c:4063 src/pulse/channelmap.c:103
#: src/pulse/channelmap.c:771
msgid "Mono"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4066 src/pulse/channelmap.c:775
+#: src/modules/alsa/alsa-mixer.c:4064 src/pulse/channelmap.c:775
msgid "Stereo"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4074 src/modules/alsa/alsa-mixer.c:4075
+#: src/modules/alsa/alsa-mixer.c:4072 src/modules/alsa/alsa-mixer.c:4073
msgid "Multichannel"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4076
+#: src/modules/alsa/alsa-mixer.c:4074
msgid "Analog Surround 2.1"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4077
+#: src/modules/alsa/alsa-mixer.c:4075
msgid "Analog Surround 3.0"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4078
+#: src/modules/alsa/alsa-mixer.c:4076
msgid "Analog Surround 3.1"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4079
+#: src/modules/alsa/alsa-mixer.c:4077
msgid "Analog Surround 4.0"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4080
+#: src/modules/alsa/alsa-mixer.c:4078
msgid "Analog Surround 4.1"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4081
+#: src/modules/alsa/alsa-mixer.c:4079
msgid "Analog Surround 5.0"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4082
+#: src/modules/alsa/alsa-mixer.c:4080
msgid "Analog Surround 5.1"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4083
+#: src/modules/alsa/alsa-mixer.c:4081
msgid "Analog Surround 6.0"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4084
+#: src/modules/alsa/alsa-mixer.c:4082
msgid "Analog Surround 6.1"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4085
+#: src/modules/alsa/alsa-mixer.c:4083
msgid "Analog Surround 7.0"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4086
+#: src/modules/alsa/alsa-mixer.c:4084
msgid "Analog Surround 7.1"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4087
+#: src/modules/alsa/alsa-mixer.c:4085
msgid "Digital Stereo (IEC958)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4088
-msgid "Digital Passthrough (IEC958)"
+#: src/modules/alsa/alsa-mixer.c:4086
+msgid "Digital Passthrough (IEC958)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4089
+#: src/modules/alsa/alsa-mixer.c:4087
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4090
+#: src/modules/alsa/alsa-mixer.c:4088
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4091
+#: src/modules/alsa/alsa-mixer.c:4089
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4092
+#: src/modules/alsa/alsa-mixer.c:4090
msgid "Digital Stereo (HDMI)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4093
+#: src/modules/alsa/alsa-mixer.c:4091
msgid "Digital Surround 5.1 (HDMI)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4226
+#: src/modules/alsa/alsa-mixer.c:4224
msgid "Analog Mono Duplex"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4227
+#: src/modules/alsa/alsa-mixer.c:4225
msgid "Analog Stereo Duplex"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4228
+#: src/modules/alsa/alsa-mixer.c:4226
msgid "Digital Stereo Duplex (IEC958)"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4229
+#: src/modules/alsa/alsa-mixer.c:4227
msgid "Multichannel Duplex"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4230
+#: src/modules/alsa/alsa-mixer.c:4228
msgid "Stereo Duplex"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4231 src/modules/alsa/module-alsa-card.c:189
-#: src/modules/bluetooth/module-bluez5-device.c:2012
+#: src/modules/alsa/alsa-mixer.c:4229 src/modules/alsa/module-alsa-card.c:187
+#: src/modules/bluetooth/module-bluez5-device.c:2159
msgid "Off"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4330
+#: src/modules/alsa/alsa-mixer.c:4328
#, c-format
msgid "%s Output"
msgstr ""
-#: src/modules/alsa/alsa-mixer.c:4338
+#: src/modules/alsa/alsa-mixer.c:4336
#, c-format
msgid "%s Input"
msgstr ""
-#: src/modules/alsa/alsa-sink.c:651 src/modules/alsa/alsa-sink.c:841
+#: src/modules/alsa/alsa-sink.c:578
#, c-format
msgid ""
"ALSA woke us up to write new data to the device, but there was actually "
@@ -774,7 +767,18 @@ msgid ""
"returned 0 or another value < min_avail."
msgstr ""
-#: src/modules/alsa/alsa-source.c:610 src/modules/alsa/alsa-source.c:776
+#: src/modules/alsa/alsa-sink.c:762
+#, c-format
+msgid ""
+"ALSA woke us up to write new data to the device, but there was actually "
+"nothing to write!\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers.\n"
+"We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
+"returned 0 or another value < min_avail."
+msgstr ""
+
+#: src/modules/alsa/alsa-source.c:535
#, c-format
msgid ""
"ALSA woke us up to read new data from the device, but there was actually "
@@ -785,37 +789,36 @@ msgid ""
"returned 0 or another value < min_avail."
msgstr ""
-#: src/modules/alsa/alsa-util.c:1173 src/modules/alsa/alsa-util.c:1267
+#: src/modules/alsa/alsa-source.c:686
#, c-format
msgid ""
-"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
-"ms).\n"
+"ALSA woke us up to read new data from the device, but there was actually "
+"nothing to read!\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
-"to the ALSA developers."
-msgid_plural ""
+"to the ALSA developers.\n"
+"We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
+"returned 0 or another value < min_avail."
+msgstr ""
+
+#: src/modules/alsa/alsa-util.c:1168 src/modules/alsa/alsa-util.c:1256
+#, c-format
+msgid ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
-msgstr[0] ""
-msgstr[1] ""
+msgstr ""
-#: src/modules/alsa/alsa-util.c:1239
+#: src/modules/alsa/alsa-util.c:1231
#, c-format
msgid ""
-"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
-"%lu ms).\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
-"to the ALSA developers."
-msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
-msgstr[0] ""
-msgstr[1] ""
+msgstr ""
-#: src/modules/alsa/alsa-util.c:1286
+#: src/modules/alsa/alsa-util.c:1272
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
@@ -824,75 +827,69 @@ msgid ""
"to the ALSA developers."
msgstr ""
-#: src/modules/alsa/alsa-util.c:1329
+#: src/modules/alsa/alsa-util.c:1315
#, c-format
msgid ""
-"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
-"(%lu ms).\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
-"to the ALSA developers."
-msgid_plural ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
"(%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
-msgstr[0] ""
-msgstr[1] ""
+msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1741
-#: src/modules/bluetooth/module-bluez5-device.c:1763
-#: src/modules/bluetooth/module-bluez5-device.c:1769
-#: src/modules/bluetooth/module-bluez5-device.c:1795
+#: src/modules/bluetooth/module-bluez5-device.c:1888
+#: src/modules/bluetooth/module-bluez5-device.c:1910
+#: src/modules/bluetooth/module-bluez5-device.c:1916
+#: src/modules/bluetooth/module-bluez5-device.c:1942
msgid "Bluetooth Input"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1742
-#: src/modules/bluetooth/module-bluez5-device.c:1758
-#: src/modules/bluetooth/module-bluez5-device.c:1796
+#: src/modules/bluetooth/module-bluez5-device.c:1889
+#: src/modules/bluetooth/module-bluez5-device.c:1905
+#: src/modules/bluetooth/module-bluez5-device.c:1943
msgid "Bluetooth Output"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1747
+#: src/modules/bluetooth/module-bluez5-device.c:1894
msgid "Headset"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1752
+#: src/modules/bluetooth/module-bluez5-device.c:1899
msgid "Handsfree"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1770
+#: src/modules/bluetooth/module-bluez5-device.c:1917
msgid "Headphone"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1775
+#: src/modules/bluetooth/module-bluez5-device.c:1922
msgid "Portable"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1780
+#: src/modules/bluetooth/module-bluez5-device.c:1927
msgid "Car"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1785
+#: src/modules/bluetooth/module-bluez5-device.c:1932
msgid "HiFi"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1790
+#: src/modules/bluetooth/module-bluez5-device.c:1937
msgid "Phone"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1837
+#: src/modules/bluetooth/module-bluez5-device.c:1984
msgid "High Fidelity Playback (A2DP Sink)"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1849
+#: src/modules/bluetooth/module-bluez5-device.c:1996
msgid "High Fidelity Capture (A2DP Source)"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1861
+#: src/modules/bluetooth/module-bluez5-device.c:2008
msgid "Headset Head Unit (HSP/HFP)"
msgstr ""
-#: src/modules/bluetooth/module-bluez5-device.c:1874
+#: src/modules/bluetooth/module-bluez5-device.c:2021
msgid "Headset Audio Gateway (HSP/HFP)"
msgstr ""
@@ -970,15 +967,10 @@ msgstr ""
msgid "Clocked NULL sink"
msgstr ""
-#: src/modules/module-null-sink.c:333
+#: src/modules/module-null-sink.c:292
msgid "Null Output"
msgstr ""
-#: src/modules/module-null-sink.c:345 src/utils/pactl.c:1058
-#, c-format
-msgid "Failed to set format: invalid format string %s"
-msgstr ""
-
#: src/modules/module-rygel-media-server.c:506
#: src/modules/module-rygel-media-server.c:544
#: src/modules/module-rygel-media-server.c:903
@@ -1025,7 +1017,7 @@ msgstr ""
msgid "Unknown device model"
msgstr ""
-#: src/modules/raop/raop-sink.c:511
+#: src/modules/raop/raop-sink.c:507
msgid "RAOP standard profile"
msgstr ""
@@ -1259,15 +1251,15 @@ msgstr ""
msgid "Surround 7.1"
msgstr ""
-#: src/pulse/client-conf-x11.c:61 src/utils/pax11publish.c:97
+#: src/pulse/client-conf-x11.c:53 src/utils/pax11publish.c:97
msgid "xcb_connect() failed"
msgstr ""
-#: src/pulse/client-conf-x11.c:66 src/utils/pax11publish.c:102
+#: src/pulse/client-conf-x11.c:58 src/utils/pax11publish.c:102
msgid "xcb_connection_has_error() returned true"
msgstr ""
-#: src/pulse/client-conf-x11.c:102
+#: src/pulse/client-conf-x11.c:94
msgid "Failed to parse cookie data"
msgstr ""
@@ -1306,7 +1298,7 @@ msgstr ""
#, c-format
msgid ""
"XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! (This could "
-"e.g. happen if you try to connect to a non-root PulseAudio as a root user, "
+"e g happen if you try to connect to a non-root PulseAudio as a root user, "
"over the native protocol. Don't do that.)"
msgstr ""
@@ -1337,11 +1329,11 @@ msgstr ""
msgid "Invalid log target."
msgstr ""
-#: src/pulsecore/sink.c:3516
+#: src/pulsecore/sink.c:3508
msgid "Built-in Audio"
msgstr ""
-#: src/pulsecore/sink.c:3521
+#: src/pulsecore/sink.c:3513
msgid "Modem"
msgstr ""
@@ -1616,7 +1608,7 @@ msgstr ""
msgid "pa_stream_connect_record() failed: %s"
msgstr ""
-#: src/utils/pacat.c:514 src/utils/pactl.c:1454
+#: src/utils/pacat.c:514 src/utils/pactl.c:1446
#, c-format
msgid "Connection failure: %s"
msgstr ""
@@ -1751,7 +1743,7 @@ msgid ""
"Linked with libpulse %s\n"
msgstr ""
-#: src/utils/pacat.c:852 src/utils/pactl.c:1656
+#: src/utils/pacat.c:852 src/utils/pactl.c:1648
#, c-format
msgid "Invalid client name '%s'"
msgstr ""
@@ -1822,7 +1814,7 @@ msgid ""
"specification from file."
msgstr ""
-#: src/utils/pacat.c:1079 src/utils/pactl.c:1720
+#: src/utils/pacat.c:1079 src/utils/pactl.c:1712
msgid "Failed to determine sample specification from file."
msgstr ""
@@ -1856,7 +1848,7 @@ msgstr ""
msgid "Failed to set media name."
msgstr ""
-#: src/utils/pacat.c:1160 src/utils/pactl.c:2070
+#: src/utils/pacat.c:1160 src/utils/pactl.c:2062
msgid "pa_mainloop_new() failed."
msgstr ""
@@ -1864,11 +1856,11 @@ msgstr ""
msgid "io_new() failed."
msgstr ""
-#: src/utils/pacat.c:1190 src/utils/pactl.c:2082
+#: src/utils/pacat.c:1190 src/utils/pactl.c:2074
msgid "pa_context_new() failed."
msgstr ""
-#: src/utils/pacat.c:1198 src/utils/pactl.c:2088
+#: src/utils/pacat.c:1198 src/utils/pactl.c:2080
#, c-format
msgid "pa_context_connect() failed: %s"
msgstr ""
@@ -1877,20 +1869,20 @@ msgstr ""
msgid "pa_context_rttime_new() failed."
msgstr ""
-#: src/utils/pacat.c:1211 src/utils/pactl.c:2093
+#: src/utils/pacat.c:1211 src/utils/pactl.c:2085
msgid "pa_mainloop_run() failed."
msgstr ""
-#: src/utils/pacmd.c:51 src/utils/pactl.c:1578
+#: src/utils/pacmd.c:51 src/utils/pactl.c:1570
msgid "NAME [ARGS ...]"
msgstr ""
-#: src/utils/pacmd.c:52 src/utils/pacmd.c:60 src/utils/pactl.c:1579
+#: src/utils/pacmd.c:52 src/utils/pacmd.c:60 src/utils/pactl.c:1571
msgid "NAME|#N"
msgstr ""
-#: src/utils/pacmd.c:53 src/utils/pacmd.c:63 src/utils/pactl.c:1577
-#: src/utils/pactl.c:1583
+#: src/utils/pacmd.c:53 src/utils/pacmd.c:63 src/utils/pactl.c:1569
+#: src/utils/pactl.c:1575
msgid "NAME"
msgstr ""
@@ -1902,7 +1894,7 @@ msgstr ""
msgid "#N VOLUME"
msgstr ""
-#: src/utils/pacmd.c:56 src/utils/pacmd.c:70 src/utils/pactl.c:1581
+#: src/utils/pacmd.c:56 src/utils/pacmd.c:70 src/utils/pactl.c:1573
msgid "NAME|#N 1|0"
msgstr ""
@@ -1938,7 +1930,7 @@ msgstr ""
msgid "FILENAME SINK|#N"
msgstr ""
-#: src/utils/pacmd.c:69 src/utils/pactl.c:1580
+#: src/utils/pacmd.c:69 src/utils/pactl.c:1572
msgid "#N SINK|SOURCE"
msgstr ""
@@ -1946,15 +1938,15 @@ msgstr ""
msgid "1|0"
msgstr ""
-#: src/utils/pacmd.c:72 src/utils/pactl.c:1582
+#: src/utils/pacmd.c:72 src/utils/pactl.c:1574
msgid "CARD PROFILE"
msgstr ""
-#: src/utils/pacmd.c:73 src/utils/pactl.c:1584
+#: src/utils/pacmd.c:73 src/utils/pactl.c:1576
msgid "NAME|#N PORT"
msgstr ""
-#: src/utils/pacmd.c:74 src/utils/pactl.c:1590
+#: src/utils/pacmd.c:74 src/utils/pactl.c:1582
msgid "CARD-NAME|CARD-#N PORT OFFSET"
msgstr ""
@@ -2031,30 +2023,25 @@ msgstr ""
#: src/utils/pactl.c:170
#, c-format
-msgid "Currently in use: %u block containing %s bytes total.\n"
-msgid_plural "Currently in use: %u blocks containing %s bytes total.\n"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr ""
-#: src/utils/pactl.c:176
+#: src/utils/pactl.c:173
#, c-format
-msgid "Allocated during whole lifetime: %u block containing %s bytes total.\n"
-msgid_plural ""
-"Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr ""
-#: src/utils/pactl.c:182
+#: src/utils/pactl.c:176
#, c-format
msgid "Sample cache size: %s\n"
msgstr ""
-#: src/utils/pactl.c:191
+#: src/utils/pactl.c:185
#, c-format
msgid "Failed to get server information: %s"
msgstr ""
-#: src/utils/pactl.c:196
+#: src/utils/pactl.c:190
#, c-format
msgid ""
"Server String: %s\n"
@@ -2065,7 +2052,7 @@ msgid ""
"Tile Size: %zu\n"
msgstr ""
-#: src/utils/pactl.c:212
+#: src/utils/pactl.c:206
#, c-format
msgid ""
"User Name: %s\n"
@@ -2079,12 +2066,12 @@ msgid ""
"Cookie: %04x:%04x\n"
msgstr ""
-#: src/utils/pactl.c:261 src/utils/pactl.c:908 src/utils/pactl.c:986
+#: src/utils/pactl.c:255 src/utils/pactl.c:900 src/utils/pactl.c:978
#, c-format
msgid "Failed to get sink information: %s"
msgstr ""
-#: src/utils/pactl.c:287
+#: src/utils/pactl.c:281
#, c-format
msgid ""
"Sink #%u\n"
@@ -2106,27 +2093,27 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:331 src/utils/pactl.c:437 src/utils/pactl.c:598
+#: src/utils/pactl.c:325 src/utils/pactl.c:431 src/utils/pactl.c:592
#, c-format
msgid "\tPorts:\n"
msgstr ""
-#: src/utils/pactl.c:338 src/utils/pactl.c:444
+#: src/utils/pactl.c:332 src/utils/pactl.c:438
#, c-format
msgid "\tActive Port: %s\n"
msgstr ""
-#: src/utils/pactl.c:344 src/utils/pactl.c:450
+#: src/utils/pactl.c:338 src/utils/pactl.c:444
#, c-format
msgid "\tFormats:\n"
msgstr ""
-#: src/utils/pactl.c:368 src/utils/pactl.c:928 src/utils/pactl.c:1001
+#: src/utils/pactl.c:362 src/utils/pactl.c:920 src/utils/pactl.c:993
#, c-format
msgid "Failed to get source information: %s"
msgstr ""
-#: src/utils/pactl.c:394
+#: src/utils/pactl.c:388
#, c-format
msgid ""
"Source #%u\n"
@@ -2148,20 +2135,20 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:422 src/utils/pactl.c:492 src/utils/pactl.c:535
-#: src/utils/pactl.c:577 src/utils/pactl.c:675 src/utils/pactl.c:676
-#: src/utils/pactl.c:687 src/utils/pactl.c:745 src/utils/pactl.c:746
-#: src/utils/pactl.c:757 src/utils/pactl.c:808 src/utils/pactl.c:809
-#: src/utils/pactl.c:815
+#: src/utils/pactl.c:416 src/utils/pactl.c:486 src/utils/pactl.c:529
+#: src/utils/pactl.c:571 src/utils/pactl.c:669 src/utils/pactl.c:670
+#: src/utils/pactl.c:681 src/utils/pactl.c:739 src/utils/pactl.c:740
+#: src/utils/pactl.c:751 src/utils/pactl.c:802 src/utils/pactl.c:803
+#: src/utils/pactl.c:809
msgid "n/a"
msgstr ""
-#: src/utils/pactl.c:461 src/utils/pactl.c:865
+#: src/utils/pactl.c:455 src/utils/pactl.c:859
#, c-format
msgid "Failed to get module information: %s"
msgstr ""
-#: src/utils/pactl.c:484
+#: src/utils/pactl.c:478
#, c-format
msgid ""
"Module #%u\n"
@@ -2172,12 +2159,12 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:503
+#: src/utils/pactl.c:497
#, c-format
msgid "Failed to get client information: %s"
msgstr ""
-#: src/utils/pactl.c:529
+#: src/utils/pactl.c:523
#, c-format
msgid ""
"Client #%u\n"
@@ -2187,12 +2174,12 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:546
+#: src/utils/pactl.c:540
#, c-format
msgid "Failed to get card information: %s"
msgstr ""
-#: src/utils/pactl.c:569
+#: src/utils/pactl.c:563
#, c-format
msgid ""
"Card #%u\n"
@@ -2203,39 +2190,39 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:585
+#: src/utils/pactl.c:579
#, c-format
msgid "\tProfiles:\n"
msgstr ""
-#: src/utils/pactl.c:587
+#: src/utils/pactl.c:581
#, c-format
msgid "\t\t%s: %s (sinks: %u, sources: %u, priority: %u, available: %s)\n"
msgstr ""
-#: src/utils/pactl.c:592
+#: src/utils/pactl.c:586
#, c-format
msgid "\tActive Profile: %s\n"
msgstr ""
-#: src/utils/pactl.c:606
+#: src/utils/pactl.c:600
#, c-format
msgid ""
"\t\t\tProperties:\n"
"\t\t\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:611
+#: src/utils/pactl.c:605
#, c-format
msgid "\t\t\tPart of profile(s): %s"
msgstr ""
-#: src/utils/pactl.c:628 src/utils/pactl.c:948 src/utils/pactl.c:1016
+#: src/utils/pactl.c:622 src/utils/pactl.c:940 src/utils/pactl.c:1008
#, c-format
msgid "Failed to get sink input information: %s"
msgstr ""
-#: src/utils/pactl.c:657
+#: src/utils/pactl.c:651
#, c-format
msgid ""
"Sink Input #%u\n"
@@ -2257,12 +2244,12 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:698 src/utils/pactl.c:968 src/utils/pactl.c:1031
+#: src/utils/pactl.c:692 src/utils/pactl.c:960 src/utils/pactl.c:1023
#, c-format
msgid "Failed to get source output information: %s"
msgstr ""
-#: src/utils/pactl.c:727
+#: src/utils/pactl.c:721
#, c-format
msgid ""
"Source Output #%u\n"
@@ -2284,12 +2271,12 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:768
+#: src/utils/pactl.c:762
#, c-format
msgid "Failed to get sample information: %s"
msgstr ""
-#: src/utils/pactl.c:795
+#: src/utils/pactl.c:789
#, c-format
msgid ""
"Sample #%u\n"
@@ -2306,156 +2293,157 @@ msgid ""
"\t\t%s\n"
msgstr ""
-#: src/utils/pactl.c:823 src/utils/pactl.c:833
+#: src/utils/pactl.c:817 src/utils/pactl.c:827
#, c-format
msgid "Failure: %s"
msgstr ""
-#: src/utils/pactl.c:872
+#: src/utils/pactl.c:866
#, c-format
msgid "Failed to unload module: Module %s not loaded"
msgstr ""
-#: src/utils/pactl.c:890
+#: src/utils/pactl.c:884
#, c-format
msgid ""
-"Failed to set volume: You tried to set volumes for %d channel, whereas "
-"channel(s) supported = %d\n"
-msgid_plural ""
"Failed to set volume: You tried to set volumes for %d channels, whereas "
-"channel(s) supported = %d\n"
-msgstr[0] ""
-msgstr[1] ""
+"channel/s supported = %d\n"
+msgstr ""
-#: src/utils/pactl.c:1101
+#: src/utils/pactl.c:1050
+#, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr ""
+
+#: src/utils/pactl.c:1093
#, c-format
msgid "Failed to upload sample: %s"
msgstr ""
-#: src/utils/pactl.c:1118
+#: src/utils/pactl.c:1110
msgid "Premature end of file"
msgstr ""
-#: src/utils/pactl.c:1138
+#: src/utils/pactl.c:1130
msgid "new"
msgstr ""
-#: src/utils/pactl.c:1141
+#: src/utils/pactl.c:1133
msgid "change"
msgstr ""
-#: src/utils/pactl.c:1144
+#: src/utils/pactl.c:1136
msgid "remove"
msgstr ""
-#: src/utils/pactl.c:1147 src/utils/pactl.c:1182
+#: src/utils/pactl.c:1139 src/utils/pactl.c:1174
msgid "unknown"
msgstr ""
-#: src/utils/pactl.c:1155
+#: src/utils/pactl.c:1147
msgid "sink"
msgstr ""
-#: src/utils/pactl.c:1158
+#: src/utils/pactl.c:1150
msgid "source"
msgstr ""
-#: src/utils/pactl.c:1161
+#: src/utils/pactl.c:1153
msgid "sink-input"
msgstr ""
-#: src/utils/pactl.c:1164
+#: src/utils/pactl.c:1156
msgid "source-output"
msgstr ""
-#: src/utils/pactl.c:1167
+#: src/utils/pactl.c:1159
msgid "module"
msgstr ""
-#: src/utils/pactl.c:1170
+#: src/utils/pactl.c:1162
msgid "client"
msgstr ""
-#: src/utils/pactl.c:1173
+#: src/utils/pactl.c:1165
msgid "sample-cache"
msgstr ""
-#: src/utils/pactl.c:1176
+#: src/utils/pactl.c:1168
msgid "server"
msgstr ""
-#: src/utils/pactl.c:1179
+#: src/utils/pactl.c:1171
msgid "card"
msgstr ""
-#: src/utils/pactl.c:1188
+#: src/utils/pactl.c:1180
#, c-format
msgid "Event '%s' on %s #%u\n"
msgstr ""
-#: src/utils/pactl.c:1460
+#: src/utils/pactl.c:1452
msgid "Got SIGINT, exiting."
msgstr ""
-#: src/utils/pactl.c:1493
+#: src/utils/pactl.c:1485
msgid "Invalid volume specification"
msgstr ""
-#: src/utils/pactl.c:1516
+#: src/utils/pactl.c:1508
msgid "Volume outside permissible range.\n"
msgstr ""
-#: src/utils/pactl.c:1529
+#: src/utils/pactl.c:1521
msgid "Invalid number of volume specifications.\n"
msgstr ""
-#: src/utils/pactl.c:1541
+#: src/utils/pactl.c:1533
msgid "Inconsistent volume specification.\n"
msgstr ""
-#: src/utils/pactl.c:1571 src/utils/pactl.c:1572 src/utils/pactl.c:1573
-#: src/utils/pactl.c:1574 src/utils/pactl.c:1575 src/utils/pactl.c:1576
-#: src/utils/pactl.c:1577 src/utils/pactl.c:1578 src/utils/pactl.c:1579
-#: src/utils/pactl.c:1580 src/utils/pactl.c:1581 src/utils/pactl.c:1582
-#: src/utils/pactl.c:1583 src/utils/pactl.c:1584 src/utils/pactl.c:1585
-#: src/utils/pactl.c:1586 src/utils/pactl.c:1587 src/utils/pactl.c:1588
-#: src/utils/pactl.c:1589 src/utils/pactl.c:1590 src/utils/pactl.c:1591
+#: src/utils/pactl.c:1563 src/utils/pactl.c:1564 src/utils/pactl.c:1565
+#: src/utils/pactl.c:1566 src/utils/pactl.c:1567 src/utils/pactl.c:1568
+#: src/utils/pactl.c:1569 src/utils/pactl.c:1570 src/utils/pactl.c:1571
+#: src/utils/pactl.c:1572 src/utils/pactl.c:1573 src/utils/pactl.c:1574
+#: src/utils/pactl.c:1575 src/utils/pactl.c:1576 src/utils/pactl.c:1577
+#: src/utils/pactl.c:1578 src/utils/pactl.c:1579 src/utils/pactl.c:1580
+#: src/utils/pactl.c:1581 src/utils/pactl.c:1582 src/utils/pactl.c:1583
msgid "[options]"
msgstr ""
-#: src/utils/pactl.c:1573
+#: src/utils/pactl.c:1565
msgid "[TYPE]"
msgstr ""
-#: src/utils/pactl.c:1575
+#: src/utils/pactl.c:1567
msgid "FILENAME [NAME]"
msgstr ""
-#: src/utils/pactl.c:1576
+#: src/utils/pactl.c:1568
msgid "NAME [SINK]"
msgstr ""
-#: src/utils/pactl.c:1585
+#: src/utils/pactl.c:1577
msgid "NAME|#N VOLUME [VOLUME ...]"
msgstr ""
-#: src/utils/pactl.c:1586
+#: src/utils/pactl.c:1578
msgid "#N VOLUME [VOLUME ...]"
msgstr ""
-#: src/utils/pactl.c:1587
+#: src/utils/pactl.c:1579
msgid "NAME|#N 1|0|toggle"
msgstr ""
-#: src/utils/pactl.c:1588
+#: src/utils/pactl.c:1580
msgid "#N 1|0|toggle"
msgstr ""
-#: src/utils/pactl.c:1589
+#: src/utils/pactl.c:1581
msgid "#N FORMATS"
msgstr ""
-#: src/utils/pactl.c:1592
+#: src/utils/pactl.c:1584
#, c-format
msgid ""
"\n"
@@ -2463,7 +2451,7 @@ msgid ""
"can be used to specify the default sink, source and monitor.\n"
msgstr ""
-#: src/utils/pactl.c:1595
+#: src/utils/pactl.c:1587
#, c-format
msgid ""
"\n"
@@ -2476,7 +2464,7 @@ msgid ""
"server\n"
msgstr ""
-#: src/utils/pactl.c:1636
+#: src/utils/pactl.c:1628
#, c-format
msgid ""
"pactl %s\n"
@@ -2484,155 +2472,155 @@ msgid ""
"Linked with libpulse %s\n"
msgstr ""
-#: src/utils/pactl.c:1692
+#: src/utils/pactl.c:1684
#, c-format
msgid "Specify nothing, or one of: %s"
msgstr ""
-#: src/utils/pactl.c:1702
+#: src/utils/pactl.c:1694
msgid "Please specify a sample file to load"
msgstr ""
-#: src/utils/pactl.c:1715
+#: src/utils/pactl.c:1707
msgid "Failed to open sound file."
msgstr ""
-#: src/utils/pactl.c:1727
+#: src/utils/pactl.c:1719
msgid "Warning: Failed to determine sample specification from file."
msgstr ""
-#: src/utils/pactl.c:1737
+#: src/utils/pactl.c:1729
msgid "You have to specify a sample name to play"
msgstr ""
-#: src/utils/pactl.c:1749
+#: src/utils/pactl.c:1741
msgid "You have to specify a sample name to remove"
msgstr ""
-#: src/utils/pactl.c:1758
+#: src/utils/pactl.c:1750
msgid "You have to specify a sink input index and a sink"
msgstr ""
-#: src/utils/pactl.c:1768
+#: src/utils/pactl.c:1760
msgid "You have to specify a source output index and a source"
msgstr ""
-#: src/utils/pactl.c:1783
+#: src/utils/pactl.c:1775
msgid "You have to specify a module name and arguments."
msgstr ""
-#: src/utils/pactl.c:1803
+#: src/utils/pactl.c:1795
msgid "You have to specify a module index or name"
msgstr ""
-#: src/utils/pactl.c:1816
+#: src/utils/pactl.c:1808
msgid ""
"You may not specify more than one sink. You have to specify a boolean value."
msgstr ""
-#: src/utils/pactl.c:1821 src/utils/pactl.c:1841
+#: src/utils/pactl.c:1813 src/utils/pactl.c:1833
msgid "Invalid suspend specification."
msgstr ""
-#: src/utils/pactl.c:1836
+#: src/utils/pactl.c:1828
msgid ""
"You may not specify more than one source. You have to specify a boolean "
"value."
msgstr ""
-#: src/utils/pactl.c:1853
+#: src/utils/pactl.c:1845
msgid "You have to specify a card name/index and a profile name"
msgstr ""
-#: src/utils/pactl.c:1864
+#: src/utils/pactl.c:1856
msgid "You have to specify a sink name/index and a port name"
msgstr ""
-#: src/utils/pactl.c:1875
+#: src/utils/pactl.c:1867
msgid "You have to specify a sink name"
msgstr ""
-#: src/utils/pactl.c:1885
+#: src/utils/pactl.c:1877
msgid "You have to specify a source name/index and a port name"
msgstr ""
-#: src/utils/pactl.c:1896
+#: src/utils/pactl.c:1888
msgid "You have to specify a source name"
msgstr ""
-#: src/utils/pactl.c:1906
+#: src/utils/pactl.c:1898
msgid "You have to specify a sink name/index and a volume"
msgstr ""
-#: src/utils/pactl.c:1919
+#: src/utils/pactl.c:1911
msgid "You have to specify a source name/index and a volume"
msgstr ""
-#: src/utils/pactl.c:1932
+#: src/utils/pactl.c:1924
msgid "You have to specify a sink input index and a volume"
msgstr ""
-#: src/utils/pactl.c:1937
+#: src/utils/pactl.c:1929
msgid "Invalid sink input index"
msgstr ""
-#: src/utils/pactl.c:1948
+#: src/utils/pactl.c:1940
msgid "You have to specify a source output index and a volume"
msgstr ""
-#: src/utils/pactl.c:1953
+#: src/utils/pactl.c:1945
msgid "Invalid source output index"
msgstr ""
-#: src/utils/pactl.c:1964
+#: src/utils/pactl.c:1956
msgid ""
"You have to specify a sink name/index and a mute action (0, 1, or 'toggle')"
msgstr ""
-#: src/utils/pactl.c:1969 src/utils/pactl.c:1984 src/utils/pactl.c:2004
-#: src/utils/pactl.c:2022
+#: src/utils/pactl.c:1961 src/utils/pactl.c:1976 src/utils/pactl.c:1996
+#: src/utils/pactl.c:2014
msgid "Invalid mute specification"
msgstr ""
-#: src/utils/pactl.c:1979
+#: src/utils/pactl.c:1971
msgid ""
"You have to specify a source name/index and a mute action (0, 1, or 'toggle')"
msgstr ""
-#: src/utils/pactl.c:1994
+#: src/utils/pactl.c:1986
msgid ""
"You have to specify a sink input index and a mute action (0, 1, or 'toggle')"
msgstr ""
-#: src/utils/pactl.c:1999
+#: src/utils/pactl.c:1991
msgid "Invalid sink input index specification"
msgstr ""
-#: src/utils/pactl.c:2012
+#: src/utils/pactl.c:2004
msgid ""
"You have to specify a source output index and a mute action (0, 1, or "
"'toggle')"
msgstr ""
-#: src/utils/pactl.c:2017
+#: src/utils/pactl.c:2009
msgid "Invalid source output index specification"
msgstr ""
-#: src/utils/pactl.c:2034
+#: src/utils/pactl.c:2026
msgid ""
"You have to specify a sink index and a semicolon-separated list of supported "
"formats"
msgstr ""
-#: src/utils/pactl.c:2046
+#: src/utils/pactl.c:2038
msgid "You have to specify a card name/index, a port name and a latency offset"
msgstr ""
-#: src/utils/pactl.c:2053
+#: src/utils/pactl.c:2045
msgid "Could not parse latency offset"
msgstr ""
-#: src/utils/pactl.c:2065
+#: src/utils/pactl.c:2057
msgid "No valid command specified."
msgstr ""
@@ -2679,9 +2667,7 @@ msgstr ""
#: src/utils/pasuspender.c:228
#, c-format
msgid ""
-"%s [options] -- PROGRAM [ARGUMENTS ...]\n"
-"\n"
-"Temporarily suspend PulseAudio while PROGRAM runs.\n"
+"%s [options] ... \n"
"\n"
" -h, --help Show this help\n"
" --version Show version\n"
@@ -2690,7 +2676,7 @@ msgid ""
"\n"
msgstr ""
-#: src/utils/pasuspender.c:267
+#: src/utils/pasuspender.c:266
#, c-format
msgid ""
"pasuspender %s\n"
@@ -2698,17 +2684,17 @@ msgid ""
"Linked with libpulse %s\n"
msgstr ""
-#: src/utils/pasuspender.c:296
+#: src/utils/pasuspender.c:295
#, c-format
msgid "pa_mainloop_new() failed.\n"
msgstr ""
-#: src/utils/pasuspender.c:309
+#: src/utils/pasuspender.c:308
#, c-format
msgid "pa_context_new() failed.\n"
msgstr ""
-#: src/utils/pasuspender.c:321
+#: src/utils/pasuspender.c:320
#, c-format
msgid "pa_mainloop_run() failed.\n"
msgstr ""
diff --git a/po/sk.gmo b/po/sk.gmo
index 4719678..1c24ead 100644
--- a/po/sk.gmo
+++ b/po/sk.gmo
Binary files differ
diff --git a/po/sr.gmo b/po/sr.gmo
index bd931fd..17f6e0a 100644
--- a/po/sr.gmo
+++ b/po/sr.gmo
Binary files differ
diff --git a/po/sr@latin.gmo b/po/sr@latin.gmo
index 3e9c82c..a14e48a 100644
--- a/po/sr@latin.gmo
+++ b/po/sr@latin.gmo
Binary files differ
diff --git a/po/ta.gmo b/po/ta.gmo
index 1ce6ae4..0b10915 100644
--- a/po/ta.gmo
+++ b/po/ta.gmo
Binary files differ
diff --git a/po/te.gmo b/po/te.gmo
index e9400e7..c678849 100644
--- a/po/te.gmo
+++ b/po/te.gmo
Binary files differ
diff --git a/po/tr.gmo b/po/tr.gmo
index 09f379c..6536399 100644
--- a/po/tr.gmo
+++ b/po/tr.gmo
Binary files differ
diff --git a/po/zh_CN.gmo b/po/zh_CN.gmo
index 3fca8fe..f807631 100644
--- a/po/zh_CN.gmo
+++ b/po/zh_CN.gmo
Binary files differ
diff --git a/po/zh_TW.gmo b/po/zh_TW.gmo
index ab5e14a..73136cf 100644
--- a/po/zh_TW.gmo
+++ b/po/zh_TW.gmo
Binary files differ
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 5bbf0ed..475938e 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -1,24 +1,102 @@
# Chinese (Taiwan) translation for pulseaudio.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-# Cheng-Chia Tseng <pswo10680@gmail.com>, 2010, 2012.
#
+# Cheng-Chia Tseng <pswo10680@gmail.com>, 2010, 2012.
+# pan93412 <pan93412@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: PulseAudio Volume Control\n"
-"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/new\n"
-"POT-Creation-Date: 2017-09-14 03:26+0000\n"
-"PO-Revision-Date: 2017-09-14 16:30+0800\n"
-"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
-"Language-Team: zh_TW\n"
+"Report-Msgid-Bugs-To: pulseaudio-discuss (at) lists (dot) freedesktop (dot)"
+" org\n"
+"POT-Creation-Date: 2020-01-11 13:44+0800\n"
+"PO-Revision-Date: 2020-01-11 13:49+0800\n"
+"Last-Translator: pan93412 <pan93412@gmail.com>\n"
+"Language-Team: Chinese <zh-l10n@lists.linux.org.tw>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=utf-8\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.0.3\n"
-
-#: ../src/daemon/cmdline.c:113
-#, c-format
+"X-Generator: Lokalize 19.12.0\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: src/daemon/cmdline.c:113
+#, 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 (only "
+#| "returns exit code)\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"
+#| " --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 --verbose Increase the verbosity level\n"
+#| " --log-target={auto,syslog,stderr,file:PATH,newfile:PATH}\n"
+#| " 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"
+#| " (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"
+#| " --enable-memfd[=BOOL] Enable memfd 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"
msgid ""
"%s [options]\n"
"\n"
@@ -48,8 +126,7 @@ msgid ""
" (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 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 "
@@ -92,7 +169,7 @@ msgstr ""
"%s [選項]\n"
"\n"
"指令:\n"
-" -h, --help 顯示此幫助\n"
+" -h, --help 顯示此說明\n"
" --version 顯示版本\n"
" --dump-conf 傾印預設組態\n"
" --dump-modules 傾印可用模組清單\n"
@@ -115,7 +192,7 @@ msgstr ""
" (僅 root 身份可用,當有 SUID 或有 "
"RLIMIT_RTPRIO \n"
" 提升之時)\n"
-" --disallow-module-loading[=BOOL] 不允許模組使用者請求的模組\n"
+" --disallow-module-loading[=BOOL] 不允許使用者請求的模組\n"
" 在初始啟動後載入/卸載\n"
" --disallow-exit[=BOOL] 不允許使用者請求離開\n"
" --exit-idle-time=SECS 在幕後程式閒置並經過這段時間後\n"
@@ -149,15 +226,15 @@ msgstr ""
"\n"
" -n 不要載入預設指令稿檔案\n"
-#: ../src/daemon/cmdline.c:246
+#: src/daemon/cmdline.c:246
msgid "--daemonize expects boolean argument"
msgstr "--daemonize 預期布林引數"
-#: ../src/daemon/cmdline.c:254
+#: src/daemon/cmdline.c:254
msgid "--fail expects boolean argument"
msgstr "--fail 預期布林引數"
-#: ../src/daemon/cmdline.c:265
+#: src/daemon/cmdline.c:265
msgid ""
"--log-level expects log level argument (either numeric in range 0..4 or one "
"of debug, info, notice, warn, error)."
@@ -165,35 +242,38 @@ msgstr ""
"--log-level 預期記錄層級引數 (範圍 0..4 間的數字,或是後列之一: debug、"
"info、notice、warn、error)。"
-#: ../src/daemon/cmdline.c:277
+#: src/daemon/cmdline.c:277
msgid "--high-priority expects boolean argument"
msgstr "--high-priority 預期布林引數"
-#: ../src/daemon/cmdline.c:285
+#: src/daemon/cmdline.c:285
msgid "--realtime expects boolean argument"
msgstr "--realtime 預期布林引數"
-#: ../src/daemon/cmdline.c:293
+#: src/daemon/cmdline.c:293
msgid "--disallow-module-loading expects boolean argument"
msgstr "--disallow-module-loading 預期布林引數"
-#: ../src/daemon/cmdline.c:301
+#: src/daemon/cmdline.c:301
msgid "--disallow-exit expects boolean argument"
msgstr "--disallow-exit 預期布林引數"
-#: ../src/daemon/cmdline.c:309
+#: src/daemon/cmdline.c:309
msgid "--use-pid-file expects boolean argument"
msgstr "--use-pid-file 預期布林引數"
-#: ../src/daemon/cmdline.c:328
+#: src/daemon/cmdline.c:328
+#| msgid ""
+#| "Invalid log target: use either 'syslog', 'journal','stderr' or 'auto' or "
+#| "a valid file name 'file:<path>', 'newfile:<path>'."
msgid ""
-"Invalid log target: use either 'syslog', 'journal','stderr' or 'auto' or a "
+"Invalid log target: use either 'syslog', 'journal', 'stderr' or 'auto' or a "
"valid file name 'file:<path>', 'newfile:<path>'."
msgstr ""
"無效的紀錄目標:請使用「syslog」、「journal」、「stderr」或「auto」或有效的檔"
"名「file:<path>」、「newfile:<path>」。"
-#: ../src/daemon/cmdline.c:330
+#: src/daemon/cmdline.c:330
msgid ""
"Invalid log target: use either 'syslog', 'stderr' or 'auto' or a valid file "
"name 'file:<path>', 'newfile:<path>'."
@@ -201,306 +281,306 @@ msgstr ""
"無效的紀錄目標:請使用「syslog」、「stderr」或「auto」或有效的檔名「file:"
"<path>」、「newfile:<path>」。"
-#: ../src/daemon/cmdline.c:338
+#: src/daemon/cmdline.c:338
msgid "--log-time expects boolean argument"
msgstr "--log-time 預期布林引數"
-#: ../src/daemon/cmdline.c:346
+#: src/daemon/cmdline.c:346
msgid "--log-meta expects boolean argument"
msgstr "--log-meta 預期布林引數"
-#: ../src/daemon/cmdline.c:366
+#: src/daemon/cmdline.c:366
#, c-format
msgid "Invalid resample method '%s'."
msgstr "無效的重新取樣方法「%s」"
-#: ../src/daemon/cmdline.c:373
+#: src/daemon/cmdline.c:373
msgid "--system expects boolean argument"
msgstr "--system 預期布林引數"
-#: ../src/daemon/cmdline.c:381
+#: src/daemon/cmdline.c:381
msgid "--no-cpu-limit expects boolean argument"
msgstr "--no-cpu-limit 預期布林引數"
-#: ../src/daemon/cmdline.c:389
+#: src/daemon/cmdline.c:389
msgid "--disable-shm expects boolean argument"
msgstr "--disable-shm 預期布林引數"
-#: ../src/daemon/cmdline.c:397
+#: src/daemon/cmdline.c:397
msgid "--enable-memfd expects boolean argument"
msgstr "--enable-memfd 預期布林引數"
-#: ../src/daemon/daemon-conf.c:262
+#: src/daemon/daemon-conf.c:269
#, c-format
msgid "[%s:%u] Invalid log target '%s'."
msgstr "[%s:%u] 無效的記錄目標「%s」。"
-#: ../src/daemon/daemon-conf.c:277
+#: src/daemon/daemon-conf.c:284
#, c-format
msgid "[%s:%u] Invalid log level '%s'."
msgstr "[%s:%u] 無效的紀錄層級「%s」。"
-#: ../src/daemon/daemon-conf.c:292
+#: src/daemon/daemon-conf.c:299
#, c-format
msgid "[%s:%u] Invalid resample method '%s'."
msgstr "[%s:%u] 無效的重新取樣方法「%s」。"
-#: ../src/daemon/daemon-conf.c:314
+#: src/daemon/daemon-conf.c:321
#, c-format
msgid "[%s:%u] Invalid rlimit '%s'."
msgstr "[%s:%u] 無效的 rlimit「%s」。"
-#: ../src/daemon/daemon-conf.c:334
+#: src/daemon/daemon-conf.c:341
#, c-format
msgid "[%s:%u] Invalid sample format '%s'."
msgstr "[%s:%u] 無效的樣本格式「%s」。"
-#: ../src/daemon/daemon-conf.c:351 ../src/daemon/daemon-conf.c:368
+#: src/daemon/daemon-conf.c:358 src/daemon/daemon-conf.c:375
#, c-format
msgid "[%s:%u] Invalid sample rate '%s'."
msgstr "[%s:%u] 無的取樣率「%s」。"
-#: ../src/daemon/daemon-conf.c:391
+#: src/daemon/daemon-conf.c:398
#, c-format
msgid "[%s:%u] Invalid sample channels '%s'."
msgstr "[%s:%u] 無效的取樣聲道「%s」。"
-#: ../src/daemon/daemon-conf.c:408
+#: src/daemon/daemon-conf.c:415
#, c-format
msgid "[%s:%u] Invalid channel map '%s'."
msgstr "[%s:%u] 無效的聲道對應表「%s」。"
-#: ../src/daemon/daemon-conf.c:425
+#: src/daemon/daemon-conf.c:432
#, c-format
msgid "[%s:%u] Invalid number of fragments '%s'."
msgstr "[%s:%u] 無效的片段數量「%s」。"
-#: ../src/daemon/daemon-conf.c:442
+#: src/daemon/daemon-conf.c:449
#, c-format
msgid "[%s:%u] Invalid fragment size '%s'."
msgstr "[%s:%u] 無效的片段大小「%s」。"
-#: ../src/daemon/daemon-conf.c:459
+#: src/daemon/daemon-conf.c:466
#, c-format
msgid "[%s:%u] Invalid nice level '%s'."
msgstr "[%s:%u] 無效的良好層級「%s」。"
-#: ../src/daemon/daemon-conf.c:502
+#: src/daemon/daemon-conf.c:551
#, c-format
msgid "[%s:%u] Invalid server type '%s'."
msgstr "[%s:%u] 無效的伺服器類型「%s」。"
-#: ../src/daemon/daemon-conf.c:620
+#: src/daemon/daemon-conf.c:671
#, c-format
msgid "Failed to open configuration file: %s"
msgstr "未能開啟組態檔:%s"
-#: ../src/daemon/daemon-conf.c:636
+#: src/daemon/daemon-conf.c:687
msgid ""
"The specified default channel map has a different number of channels than "
"the specified default number of channels."
msgstr "指定的預設聲道對應表的聲道數與指定的預設聲道數不同。"
-#: ../src/daemon/daemon-conf.c:723
+#: src/daemon/daemon-conf.c:774
#, c-format
msgid "### Read from configuration file: %s ###\n"
msgstr "### 從此組態檔讀取:%s ###\n"
-#: ../src/daemon/dumpmodules.c:57
+#: src/daemon/dumpmodules.c:57
#, c-format
msgid "Name: %s\n"
msgstr "名稱:%s\n"
-#: ../src/daemon/dumpmodules.c:60
+#: src/daemon/dumpmodules.c:60
#, c-format
msgid "No module information available\n"
msgstr "沒有可用的模組資訊\n"
-#: ../src/daemon/dumpmodules.c:63
+#: src/daemon/dumpmodules.c:63
#, c-format
msgid "Version: %s\n"
msgstr "版本:%s\n"
-#: ../src/daemon/dumpmodules.c:65
+#: src/daemon/dumpmodules.c:65
#, c-format
msgid "Description: %s\n"
msgstr "描述:%s\n"
-#: ../src/daemon/dumpmodules.c:67
+#: src/daemon/dumpmodules.c:67
#, c-format
msgid "Author: %s\n"
msgstr "作者:%s\n"
-#: ../src/daemon/dumpmodules.c:69
+#: src/daemon/dumpmodules.c:69
#, c-format
msgid "Usage: %s\n"
msgstr "用法:%s\n"
-#: ../src/daemon/dumpmodules.c:70
+#: src/daemon/dumpmodules.c:70
#, c-format
msgid "Load Once: %s\n"
msgstr "載入一次:%s\n"
-#: ../src/daemon/dumpmodules.c:72
+#: src/daemon/dumpmodules.c:72
#, c-format
msgid "DEPRECATION WARNING: %s\n"
msgstr "反對警告:%s\n"
-#: ../src/daemon/dumpmodules.c:76
+#: src/daemon/dumpmodules.c:76
#, c-format
msgid "Path: %s\n"
msgstr "路徑:%s\n"
-#: ../src/daemon/ltdl-bind-now.c:75
+#: src/daemon/ltdl-bind-now.c:75
#, c-format
msgid "Failed to open module %s: %s"
msgstr "無法開啟模組 %s:%s"
-#: ../src/daemon/ltdl-bind-now.c:126
+#: src/daemon/ltdl-bind-now.c:126
msgid "Failed to find original lt_dlopen loader."
msgstr "找不到 original lt_dlopen loader。"
-#: ../src/daemon/ltdl-bind-now.c:131
+#: src/daemon/ltdl-bind-now.c:131
msgid "Failed to allocate new dl loader."
msgstr "未能分配新的 dl loader。"
-#: ../src/daemon/ltdl-bind-now.c:144
+#: src/daemon/ltdl-bind-now.c:144
msgid "Failed to add bind-now-loader."
msgstr "未能加入 bind-now-loader。"
-#: ../src/daemon/main.c:162
+#: src/daemon/main.c:171
#, c-format
msgid "Failed to find user '%s'."
msgstr "找不到使用者「%s」。"
-#: ../src/daemon/main.c:167
+#: src/daemon/main.c:176
#, c-format
msgid "Failed to find group '%s'."
msgstr "找不到群組「%s」。"
-#: ../src/daemon/main.c:176
+#: src/daemon/main.c:185
#, c-format
msgid "GID of user '%s' and of group '%s' don't match."
msgstr "使用者「%s」的 GID 與群組「%s」的 GID 不相符。"
-#: ../src/daemon/main.c:181
+#: src/daemon/main.c:190
#, c-format
msgid "Home directory of user '%s' is not '%s', ignoring."
msgstr "使用者「%s」的家目錄不是「%s」,忽略中。"
-#: ../src/daemon/main.c:184 ../src/daemon/main.c:189
+#: src/daemon/main.c:193 src/daemon/main.c:198
#, c-format
msgid "Failed to create '%s': %s"
msgstr "未能建立「%s」:%s"
-#: ../src/daemon/main.c:196
+#: src/daemon/main.c:205
#, c-format
msgid "Failed to change group list: %s"
msgstr "未能變更群組清單:%s"
-#: ../src/daemon/main.c:212
+#: src/daemon/main.c:221
#, c-format
msgid "Failed to change GID: %s"
msgstr "未能變更 GIC:%s"
-#: ../src/daemon/main.c:228
+#: src/daemon/main.c:237
#, c-format
msgid "Failed to change UID: %s"
msgstr "未能變更 UID:%s"
-#: ../src/daemon/main.c:257
+#: src/daemon/main.c:266
msgid "System wide mode unsupported on this platform."
msgstr "本平台未支援系統域模式。"
-#: ../src/daemon/main.c:486
+#: src/daemon/main.c:495
msgid "Failed to parse command line."
msgstr "未能解析命令列。"
-#: ../src/daemon/main.c:525
+#: src/daemon/main.c:534
msgid ""
"System mode refused for non-root user. Only starting the D-Bus server lookup "
"service."
msgstr "系統模式拒絕非 root 使用者。僅啟動 D-Bus 伺服器查看服務。"
-#: ../src/daemon/main.c:624
+#: src/daemon/main.c:633
#, c-format
msgid "Failed to kill daemon: %s"
msgstr "未能結束幕後程式:%s"
-#: ../src/daemon/main.c:653
+#: src/daemon/main.c:662
msgid ""
"This program is not intended to be run as root (unless --system is "
"specified)."
msgstr "本程式不預期以 root 身份執行(除非有指定 --system)。"
-#: ../src/daemon/main.c:656
+#: src/daemon/main.c:665
msgid "Root privileges required."
msgstr "需要 root 特權。"
-#: ../src/daemon/main.c:663
+#: src/daemon/main.c:672
msgid "--start not supported for system instances."
msgstr "--start 不支援系統實體。"
-#: ../src/daemon/main.c:703
+#: src/daemon/main.c:712
#, c-format
msgid "User-configured server at %s, refusing to start/autospawn."
msgstr "使用者於 %s 設定的伺服器,拒絕啟動/autospawn。"
-#: ../src/daemon/main.c:709
+#: src/daemon/main.c:718
#, c-format
msgid ""
"User-configured server at %s, which appears to be local. Probing deeper."
msgstr "使用者設定的伺服器位於 %s,它似乎是本機。正在深入探測。"
-#: ../src/daemon/main.c:714
+#: src/daemon/main.c:723
msgid "Running in system mode, but --disallow-exit not set."
msgstr "以系統模式執行中,但 --disallow-exit 未設定。"
-#: ../src/daemon/main.c:717
+#: src/daemon/main.c:726
msgid "Running in system mode, but --disallow-module-loading not set."
msgstr "以系統模式執行中,但 --disallow-module-loading 未設定。"
-#: ../src/daemon/main.c:720
+#: src/daemon/main.c:729
msgid "Running in system mode, forcibly disabling SHM mode."
msgstr "以系統模式執行中,強制停用 SHM 模式。"
-#: ../src/daemon/main.c:725
+#: src/daemon/main.c:734
msgid "Running in system mode, forcibly disabling exit idle time."
msgstr "以系統模式執行中,強制停用離開閒置時間。"
-#: ../src/daemon/main.c:758
+#: src/daemon/main.c:767
msgid "Failed to acquire stdio."
msgstr "未能獲取 stdio。"
-#: ../src/daemon/main.c:764 ../src/daemon/main.c:835
+#: src/daemon/main.c:773 src/daemon/main.c:844
#, c-format
msgid "pipe() failed: %s"
msgstr "pipe() 失敗:%s"
-#: ../src/daemon/main.c:769 ../src/daemon/main.c:840
+#: src/daemon/main.c:778 src/daemon/main.c:849
#, c-format
msgid "fork() failed: %s"
msgstr "fork() 失敗:%s"
-#: ../src/daemon/main.c:784 ../src/daemon/main.c:855 ../src/utils/pacat.c:562
+#: src/daemon/main.c:793 src/daemon/main.c:864 src/utils/pacat.c:562
#, c-format
msgid "read() failed: %s"
msgstr "read() 失敗:%s"
-#: ../src/daemon/main.c:790
+#: src/daemon/main.c:799
msgid "Daemon startup failed."
msgstr "幕後程式啟動失敗。"
-#: ../src/daemon/main.c:823
+#: src/daemon/main.c:832
#, c-format
msgid "setsid() failed: %s"
msgstr "setsid() 失敗:%s"
-#: ../src/daemon/main.c:950
+#: src/daemon/main.c:965
msgid "Failed to get machine ID"
msgstr "未能取得機器 ID"
-#: ../src/daemon/main.c:976
+#: src/daemon/main.c:991
msgid ""
"OK, so you are running PA in system mode. Please make sure that you actually "
"do want to do that.\n"
@@ -512,311 +592,331 @@ msgstr ""
"請閱讀 http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/"
"User/WhatIsWrongWithSystemWide/ 瞭解為何採用系統模式一般是不理想的點子。"
-#: ../src/daemon/main.c:992
+#: src/daemon/main.c:1007
msgid "pa_pid_file_create() failed."
msgstr "pa_pid_file_create() 失敗。"
-#: ../src/daemon/main.c:1024
+#: src/daemon/main.c:1039
msgid "pa_core_new() failed."
msgstr "pa_core_new() 失敗。"
-#: ../src/daemon/main.c:1094
-msgid "Failed to initialize daemon."
-msgstr "未能初始化幕後程式。"
+#: src/daemon/main.c:1109
+#| msgid "Too many arguments."
+msgid "command line arguments"
+msgstr "指令列參數"
+
+#: src/daemon/main.c:1116
+#, c-format
+msgid ""
+"Failed to initialize daemon due to errors while executing startup commands. "
+"Source of commands: %s"
+msgstr ""
+"因執行啟動指令時發生錯誤,而無法初始化幕後程式。"
+"指令來源:%s"
-#: ../src/daemon/main.c:1099
+#: src/daemon/main.c:1121
msgid "Daemon startup without any loaded modules, refusing to work."
msgstr "幕後程式啟動而沒有任何載入的模組,拒絕運作。"
-#: ../src/daemon/pulseaudio.desktop.in.h:1
+#: src/daemon/pulseaudio.desktop.in:4
msgid "PulseAudio Sound System"
msgstr "PulseAudio 音效系統"
-#: ../src/daemon/pulseaudio.desktop.in.h:2
+#: src/daemon/pulseaudio.desktop.in:5
msgid "Start the PulseAudio Sound System"
msgstr "啟動 PulseAudio 音效系統"
-#: ../src/modules/alsa/alsa-mixer.c:2378
+#: src/modules/alsa/alsa-mixer.c:2544
msgid "Input"
msgstr "輸入"
-#: ../src/modules/alsa/alsa-mixer.c:2379
+#: src/modules/alsa/alsa-mixer.c:2545
msgid "Docking Station Input"
msgstr "Docking Station 輸入"
-#: ../src/modules/alsa/alsa-mixer.c:2380
+#: src/modules/alsa/alsa-mixer.c:2546
msgid "Docking Station Microphone"
msgstr "Docking Station 麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2381
+#: src/modules/alsa/alsa-mixer.c:2547
msgid "Docking Station Line In"
msgstr "Docking Station 線路輸入"
-#: ../src/modules/alsa/alsa-mixer.c:2382 ../src/modules/alsa/alsa-mixer.c:2467
+#: src/modules/alsa/alsa-mixer.c:2548 src/modules/alsa/alsa-mixer.c:2639
msgid "Line In"
msgstr "線路輸入"
-#: ../src/modules/alsa/alsa-mixer.c:2383 ../src/modules/alsa/alsa-mixer.c:2461
-#: ../src/modules/bluetooth/module-bluez5-device.c:1773
+#: src/modules/alsa/alsa-mixer.c:2549 src/modules/alsa/alsa-mixer.c:2633
+#: src/modules/bluetooth/module-bluez5-device.c:1788
msgid "Microphone"
msgstr "麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2384 ../src/modules/alsa/alsa-mixer.c:2462
+#: src/modules/alsa/alsa-mixer.c:2550 src/modules/alsa/alsa-mixer.c:2634
msgid "Front Microphone"
msgstr "前方麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2385 ../src/modules/alsa/alsa-mixer.c:2463
+#: src/modules/alsa/alsa-mixer.c:2551 src/modules/alsa/alsa-mixer.c:2635
msgid "Rear Microphone"
msgstr "後方麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2386
+#: src/modules/alsa/alsa-mixer.c:2552
msgid "External Microphone"
msgstr "外接麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2387 ../src/modules/alsa/alsa-mixer.c:2465
+#: src/modules/alsa/alsa-mixer.c:2553 src/modules/alsa/alsa-mixer.c:2637
msgid "Internal Microphone"
msgstr "內建麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2388 ../src/modules/alsa/alsa-mixer.c:2468
+#: src/modules/alsa/alsa-mixer.c:2554 src/modules/alsa/alsa-mixer.c:2640
msgid "Radio"
msgstr "無線電"
-#: ../src/modules/alsa/alsa-mixer.c:2389 ../src/modules/alsa/alsa-mixer.c:2469
+#: src/modules/alsa/alsa-mixer.c:2555 src/modules/alsa/alsa-mixer.c:2641
msgid "Video"
msgstr "視訊"
-#: ../src/modules/alsa/alsa-mixer.c:2390
+#: src/modules/alsa/alsa-mixer.c:2556
msgid "Automatic Gain Control"
msgstr "自動增益控制"
-#: ../src/modules/alsa/alsa-mixer.c:2391
+#: src/modules/alsa/alsa-mixer.c:2557
msgid "No Automatic Gain Control"
msgstr "無自動增益控制"
-#: ../src/modules/alsa/alsa-mixer.c:2392
+#: src/modules/alsa/alsa-mixer.c:2558
msgid "Boost"
msgstr "增強"
-#: ../src/modules/alsa/alsa-mixer.c:2393
+#: src/modules/alsa/alsa-mixer.c:2559
msgid "No Boost"
msgstr "無增強"
-#: ../src/modules/alsa/alsa-mixer.c:2394
+#: src/modules/alsa/alsa-mixer.c:2560
msgid "Amplifier"
msgstr "擴大器"
-#: ../src/modules/alsa/alsa-mixer.c:2395
+#: src/modules/alsa/alsa-mixer.c:2561
msgid "No Amplifier"
msgstr "無擴大器"
-#: ../src/modules/alsa/alsa-mixer.c:2396
+#: src/modules/alsa/alsa-mixer.c:2562
msgid "Bass Boost"
msgstr "低音增強"
-#: ../src/modules/alsa/alsa-mixer.c:2397
+#: src/modules/alsa/alsa-mixer.c:2563
msgid "No Bass Boost"
msgstr "無低音增強"
-#: ../src/modules/alsa/alsa-mixer.c:2398
-#: ../src/modules/bluetooth/module-bluez5-device.c:1780
+#: src/modules/alsa/alsa-mixer.c:2564
+#: src/modules/bluetooth/module-bluez5-device.c:1795
msgid "Speaker"
msgstr "喇叭"
-#: ../src/modules/alsa/alsa-mixer.c:2399 ../src/modules/alsa/alsa-mixer.c:2471
+#: src/modules/alsa/alsa-mixer.c:2565 src/modules/alsa/alsa-mixer.c:2643
msgid "Headphones"
msgstr "頭戴式耳機"
-#: ../src/modules/alsa/alsa-mixer.c:2460
+#: src/modules/alsa/alsa-mixer.c:2632
msgid "Analog Input"
msgstr "類比輸入"
-#: ../src/modules/alsa/alsa-mixer.c:2464
+#: src/modules/alsa/alsa-mixer.c:2636
msgid "Dock Microphone"
msgstr "臺座麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2466
+#: src/modules/alsa/alsa-mixer.c:2638
msgid "Headset Microphone"
msgstr "耳麥麥克風"
-#: ../src/modules/alsa/alsa-mixer.c:2470
+#: src/modules/alsa/alsa-mixer.c:2642
msgid "Analog Output"
msgstr "類比輸出"
-#: ../src/modules/alsa/alsa-mixer.c:2472
+#: src/modules/alsa/alsa-mixer.c:2644
msgid "Headphones Mono Output"
msgstr "頭戴式耳機單聲道輸出"
-#: ../src/modules/alsa/alsa-mixer.c:2473
+#: src/modules/alsa/alsa-mixer.c:2645
msgid "LFE on Separate Mono Output"
msgstr "LFE 於分隔單聲道輸出"
-#: ../src/modules/alsa/alsa-mixer.c:2474
+#: src/modules/alsa/alsa-mixer.c:2646
msgid "Line Out"
msgstr "線路輸出"
-#: ../src/modules/alsa/alsa-mixer.c:2475
+#: src/modules/alsa/alsa-mixer.c:2647
msgid "Analog Mono Output"
msgstr "類比單聲道輸出"
-#: ../src/modules/alsa/alsa-mixer.c:2476
+#: src/modules/alsa/alsa-mixer.c:2648
msgid "Speakers"
msgstr "喇叭"
-#: ../src/modules/alsa/alsa-mixer.c:2477
+#: src/modules/alsa/alsa-mixer.c:2649
msgid "HDMI / DisplayPort"
msgstr "HDMI / DisplayPort"
-#: ../src/modules/alsa/alsa-mixer.c:2478
+#: src/modules/alsa/alsa-mixer.c:2650
msgid "Digital Output (S/PDIF)"
msgstr "數位輸出 (S/PDIF)"
-#: ../src/modules/alsa/alsa-mixer.c:2479
+#: src/modules/alsa/alsa-mixer.c:2651
msgid "Digital Input (S/PDIF)"
msgstr "數位輸入 (S/PDIF)"
-#: ../src/modules/alsa/alsa-mixer.c:2480
+#: src/modules/alsa/alsa-mixer.c:2652
msgid "Digital Passthrough (S/PDIF)"
msgstr "數位通透 (S/PDIF)"
-#: ../src/modules/alsa/alsa-mixer.c:2481
+#: src/modules/alsa/alsa-mixer.c:2653
msgid "Multichannel Input"
msgstr "多聲道輸入"
-#: ../src/modules/alsa/alsa-mixer.c:2482
+#: src/modules/alsa/alsa-mixer.c:2654
msgid "Multichannel Output"
msgstr "多聲道輸出"
-#: ../src/modules/alsa/alsa-mixer.c:3991
+#: src/modules/alsa/alsa-mixer.c:2655
+#| msgid "%s Output"
+msgid "Game Output"
+msgstr "遊戲輸出"
+
+#: src/modules/alsa/alsa-mixer.c:2656
+#| msgid "%s Output"
+msgid "Chat Output"
+msgstr "聊天輸出"
+
+#: src/modules/alsa/alsa-mixer.c:4225
msgid "Analog Mono"
msgstr "類比單聲道"
-#. Note: Not translated to "Analog Stereo Input", because the source
-#. * name gets "Input" appended to it automatically, so adding "Input"
-#. * here would lead to the source name to become "Analog Stereo Input
-#. * Input". The same logic applies to analog-stereo-output,
-#. * multichannel-input and multichannel-output.
-#: ../src/modules/alsa/alsa-mixer.c:3992 ../src/modules/alsa/alsa-mixer.c:3998
-#: ../src/modules/alsa/alsa-mixer.c:3999
+#: src/modules/alsa/alsa-mixer.c:4226 src/modules/alsa/alsa-mixer.c:4234
+#: src/modules/alsa/alsa-mixer.c:4235
msgid "Analog Stereo"
msgstr "類比立體聲"
-#: ../src/modules/alsa/alsa-mixer.c:4000 ../src/modules/alsa/alsa-mixer.c:4001
+#: src/modules/alsa/alsa-mixer.c:4227 src/pulse/channelmap.c:103
+#: src/pulse/channelmap.c:771
+msgid "Mono"
+msgstr "單聲道"
+
+#: src/modules/alsa/alsa-mixer.c:4228 src/pulse/channelmap.c:775
+msgid "Stereo"
+msgstr "立體聲"
+
+#: src/modules/alsa/alsa-mixer.c:4236 src/modules/alsa/alsa-mixer.c:4237
msgid "Multichannel"
msgstr "多聲道"
-#: ../src/modules/alsa/alsa-mixer.c:4002
+#: src/modules/alsa/alsa-mixer.c:4238
msgid "Analog Surround 2.1"
msgstr "類比環繞聲 2.1"
-#: ../src/modules/alsa/alsa-mixer.c:4003
+#: src/modules/alsa/alsa-mixer.c:4239
msgid "Analog Surround 3.0"
msgstr "類比環繞聲 3.0"
-#: ../src/modules/alsa/alsa-mixer.c:4004
+#: src/modules/alsa/alsa-mixer.c:4240
msgid "Analog Surround 3.1"
msgstr "類比環繞聲 3.1"
-#: ../src/modules/alsa/alsa-mixer.c:4005
+#: src/modules/alsa/alsa-mixer.c:4241
msgid "Analog Surround 4.0"
msgstr "類比環繞聲 4.0"
-#: ../src/modules/alsa/alsa-mixer.c:4006
+#: src/modules/alsa/alsa-mixer.c:4242
msgid "Analog Surround 4.1"
msgstr "類比環繞聲 4.1"
-#: ../src/modules/alsa/alsa-mixer.c:4007
+#: src/modules/alsa/alsa-mixer.c:4243
msgid "Analog Surround 5.0"
msgstr "類比環繞聲 5.0"
-#: ../src/modules/alsa/alsa-mixer.c:4008
+#: src/modules/alsa/alsa-mixer.c:4244
msgid "Analog Surround 5.1"
msgstr "類比環繞聲 5.1"
-#: ../src/modules/alsa/alsa-mixer.c:4009
+#: src/modules/alsa/alsa-mixer.c:4245
msgid "Analog Surround 6.0"
msgstr "類比環繞聲 6.0"
-#: ../src/modules/alsa/alsa-mixer.c:4010
+#: src/modules/alsa/alsa-mixer.c:4246
msgid "Analog Surround 6.1"
msgstr "類比環繞聲 6.1"
-#: ../src/modules/alsa/alsa-mixer.c:4011
+#: src/modules/alsa/alsa-mixer.c:4247
msgid "Analog Surround 7.0"
msgstr "類比環繞聲 7.0"
-#: ../src/modules/alsa/alsa-mixer.c:4012
+#: src/modules/alsa/alsa-mixer.c:4248
msgid "Analog Surround 7.1"
msgstr "類比環繞聲 7.1"
-#: ../src/modules/alsa/alsa-mixer.c:4013
+#: src/modules/alsa/alsa-mixer.c:4249
msgid "Digital Stereo (IEC958)"
msgstr "數位立體聲 (IEC958)"
-#: ../src/modules/alsa/alsa-mixer.c:4014
-msgid "Digital Passthrough (IEC958)"
+#: src/modules/alsa/alsa-mixer.c:4250
+#| msgid "Digital Passthrough (IEC958)"
+msgid "Digital Passthrough (IEC958)"
msgstr "數位通透 (IEC958)"
-#: ../src/modules/alsa/alsa-mixer.c:4015
+#: src/modules/alsa/alsa-mixer.c:4251
msgid "Digital Surround 4.0 (IEC958/AC3)"
msgstr "數位環繞聲 4.0 (IEC958/AC3)"
-#: ../src/modules/alsa/alsa-mixer.c:4016
+#: src/modules/alsa/alsa-mixer.c:4252
msgid "Digital Surround 5.1 (IEC958/AC3)"
msgstr "數位環繞聲 5.1 (IEC958/AC3)"
-#: ../src/modules/alsa/alsa-mixer.c:4017
+#: src/modules/alsa/alsa-mixer.c:4253
msgid "Digital Surround 5.1 (IEC958/DTS)"
msgstr "數位環繞聲 5.1 (IEC958/DTS)"
-#: ../src/modules/alsa/alsa-mixer.c:4018
+#: src/modules/alsa/alsa-mixer.c:4254
msgid "Digital Stereo (HDMI)"
msgstr "數位立體聲 (HDMI)"
-#: ../src/modules/alsa/alsa-mixer.c:4019
+#: src/modules/alsa/alsa-mixer.c:4255
msgid "Digital Surround 5.1 (HDMI)"
msgstr "數位環繞聲 5.1 (HDMI)"
-#: ../src/modules/alsa/alsa-mixer.c:4020 ../src/pulse/channelmap.c:775
-msgid "Stereo"
-msgstr "立體聲"
-
-#: ../src/modules/alsa/alsa-mixer.c:4153
+#: src/modules/alsa/alsa-mixer.c:4388
msgid "Analog Mono Duplex"
msgstr "類比單聲道雙工"
-#: ../src/modules/alsa/alsa-mixer.c:4154
+#: src/modules/alsa/alsa-mixer.c:4389
msgid "Analog Stereo Duplex"
msgstr "類比立體聲雙工"
-#: ../src/modules/alsa/alsa-mixer.c:4155
+#: src/modules/alsa/alsa-mixer.c:4390
msgid "Digital Stereo Duplex (IEC958)"
msgstr "數位立體聲雙工 (IEC958)"
-#: ../src/modules/alsa/alsa-mixer.c:4156
+#: src/modules/alsa/alsa-mixer.c:4391
msgid "Multichannel Duplex"
msgstr "多聲道雙工"
-#: ../src/modules/alsa/alsa-mixer.c:4157
+#: src/modules/alsa/alsa-mixer.c:4392
msgid "Stereo Duplex"
msgstr "立體聲雙工"
-#: ../src/modules/alsa/alsa-mixer.c:4158
-#: ../src/modules/alsa/module-alsa-card.c:186
-#: ../src/modules/bluetooth/module-bluez5-device.c:2028
+#: src/modules/alsa/alsa-mixer.c:4393 src/modules/alsa/module-alsa-card.c:188
+#: src/modules/bluetooth/module-bluez5-device.c:2043
msgid "Off"
msgstr "關閉"
-#: ../src/modules/alsa/alsa-mixer.c:4257
+#: src/modules/alsa/alsa-mixer.c:4492
#, c-format
msgid "%s Output"
msgstr "%s 輸出"
-#: ../src/modules/alsa/alsa-mixer.c:4265
+#: src/modules/alsa/alsa-mixer.c:4500
#, c-format
msgid "%s Input"
msgstr "%s 輸入"
-#: ../src/modules/alsa/alsa-sink.c:572
+#: src/modules/alsa/alsa-sink.c:652 src/modules/alsa/alsa-sink.c:842
#, c-format
msgid ""
"ALSA woke us up to write new data to the device, but there was actually "
@@ -831,22 +931,7 @@ msgstr ""
"我們被 POLLOUT 設定喚醒 -- 然而後續的 snd_pcm_avail() 傳回 0 或另一個值 < "
"min_avail。"
-#: ../src/modules/alsa/alsa-sink.c:756
-#, c-format
-msgid ""
-"ALSA woke us up to write new data to the device, but there was actually "
-"nothing to write!\n"
-"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
-"to the ALSA developers.\n"
-"We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
-"returned 0 or another value < min_avail."
-msgstr ""
-"ALSA 喚醒我們以寫入新資料至該裝置,但實際上沒有要寫入的資料!\n"
-"這很可能是 ALSA 驅動程式「%s」的臭蟲。請回報此問題給 ALSA 開發者。\n"
-"我們被 POLLOUT 設定喚醒 -- 然而後續的 snd_pcm_avail() 傳回 0 或另一個值 < "
-"min_avail。"
-
-#: ../src/modules/alsa/alsa-source.c:529
+#: src/modules/alsa/alsa-source.c:611 src/modules/alsa/alsa-source.c:777
#, c-format
msgid ""
"ALSA woke us up to read new data from the device, but there was actually "
@@ -861,44 +946,49 @@ msgstr ""
"我們被 POLLIN 設定喚醒 -- 然而後續的 snd_pcm_avail() 傳回 0 或另一個值 < "
"min_avail。"
-#: ../src/modules/alsa/alsa-source.c:680
+#: src/modules/alsa/alsa-util.c:1183 src/modules/alsa/alsa-util.c:1277
#, c-format
+#| msgid ""
+#| "snd_pcm_avail() returned a value that is exceptionally large: %lu bytes "
+#| "(%lu ms).\n"
+#| "Most likely this is a bug in the ALSA driver '%s'. Please report this "
+#| "issue to the ALSA developers."
msgid ""
-"ALSA woke us up to read new data from the device, but there was actually "
-"nothing to read!\n"
+"snd_pcm_avail() returned a value that is exceptionally large: %lu byte (%lu "
+"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
-"to the ALSA developers.\n"
-"We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
-"returned 0 or another value < min_avail."
-msgstr ""
-"ALSA 喚醒我們從該裝置讀取新資料,但實際上沒有可讀取的資料!\n"
-"這很可能是 ALSA 驅動程式「%s」的臭蟲。請回報此問題給 ALSA 開發者。\n"
-"我們被 POLLIN 設定喚醒 -- 然而後續的 snd_pcm_avail() 傳回 0 或另一個值 < "
-"min_avail。"
-
-#: ../src/modules/alsa/alsa-util.c:1168 ../src/modules/alsa/alsa-util.c:1243
-#, c-format
-msgid ""
+"to the ALSA developers."
+msgid_plural ""
"snd_pcm_avail() returned a value that is exceptionally large: %lu bytes (%lu "
"ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
-msgstr ""
+msgstr[0] ""
"snd_pcm_avail() 傳回超出預期的大值:%lu bytes (%lu ms)。\n"
"這很能是 ALSA 驅動程式「%s」的臭蟲。請回報這個問題給 ALSA 開發者。"
-#: ../src/modules/alsa/alsa-util.c:1218
+#: src/modules/alsa/alsa-util.c:1249
#, c-format
+#| msgid ""
+#| "snd_pcm_delay() returned a value that is exceptionally large: %li bytes "
+#| "(%s%lu ms).\n"
+#| "Most likely this is a bug in the ALSA driver '%s'. Please report this "
+#| "issue to the ALSA developers."
msgid ""
+"snd_pcm_delay() returned a value that is exceptionally large: %li byte (%s"
+"%lu ms).\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgid_plural ""
"snd_pcm_delay() returned a value that is exceptionally large: %li bytes (%s"
"%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
-msgstr ""
+msgstr[0] ""
"snd_pcm_delay() 傳回超出預期的大值:%li bytes (%s%lu ms)。\n"
"這很能是 ALSA 驅動程式「%s」的臭蟲。請回報這個問題給 ALSA 開發者。"
-#: ../src/modules/alsa/alsa-util.c:1259
+#: src/modules/alsa/alsa-util.c:1296
#, c-format
msgid ""
"snd_pcm_avail_delay() returned strange values: delay %lu is less than avail "
@@ -909,75 +999,85 @@ msgstr ""
"snd_pcm_avail_delay() 傳回超出預期的大值:延遲 %lu 少於可用的 %lu。\n"
"這很能是 ALSA 驅動程式「%s」的臭蟲。請回報這個問題給 ALSA 開發者。"
-#: ../src/modules/alsa/alsa-util.c:1302
+#: src/modules/alsa/alsa-util.c:1339
#, c-format
+#| msgid ""
+#| "snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu "
+#| "bytes (%lu ms).\n"
+#| "Most likely this is a bug in the ALSA driver '%s'. Please report this "
+#| "issue to the ALSA developers."
msgid ""
+"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu byte "
+"(%lu ms).\n"
+"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
+"to the ALSA developers."
+msgid_plural ""
"snd_pcm_mmap_begin() returned a value that is exceptionally large: %lu bytes "
"(%lu ms).\n"
"Most likely this is a bug in the ALSA driver '%s'. Please report this issue "
"to the ALSA developers."
-msgstr ""
+msgstr[0] ""
"snd_pcm_mmap_begin() 傳回超出預期的大值:%lu bytes (%lu ms)。\n"
"這很能是 ALSA 驅動程式「%s」的臭蟲。請回報這個問題給 ALSA 開發者。"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1763
+#: src/modules/bluetooth/module-bluez5-device.c:1772
+#: src/modules/bluetooth/module-bluez5-device.c:1794
+#: src/modules/bluetooth/module-bluez5-device.c:1800
+#: src/modules/bluetooth/module-bluez5-device.c:1826
+msgid "Bluetooth Input"
+msgstr "藍牙輸入"
+
+#: src/modules/bluetooth/module-bluez5-device.c:1773
+#: src/modules/bluetooth/module-bluez5-device.c:1789
+#: src/modules/bluetooth/module-bluez5-device.c:1827
+msgid "Bluetooth Output"
+msgstr "藍牙輸出"
+
+#: src/modules/bluetooth/module-bluez5-device.c:1778
msgid "Headset"
msgstr "耳麥"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1768
+#: src/modules/bluetooth/module-bluez5-device.c:1783
msgid "Handsfree"
msgstr "免持裝置"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1786
+#: src/modules/bluetooth/module-bluez5-device.c:1801
msgid "Headphone"
msgstr "頭戴式耳機"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1791
+#: src/modules/bluetooth/module-bluez5-device.c:1806
msgid "Portable"
msgstr "可攜裝置"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1796
+#: src/modules/bluetooth/module-bluez5-device.c:1811
msgid "Car"
msgstr "汽車"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1801
+#: src/modules/bluetooth/module-bluez5-device.c:1816
msgid "HiFi"
msgstr "HiFi"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1806
+#: src/modules/bluetooth/module-bluez5-device.c:1821
msgid "Phone"
msgstr "手機"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1758
-#: ../src/modules/bluetooth/module-bluez5-device.c:1774
-#: ../src/modules/bluetooth/module-bluez5-device.c:1812
-msgid "Bluetooth Output"
-msgstr "藍牙輸出"
-
-#: ../src/modules/bluetooth/module-bluez5-device.c:1757
-#: ../src/modules/bluetooth/module-bluez5-device.c:1779
-#: ../src/modules/bluetooth/module-bluez5-device.c:1785
-#: ../src/modules/bluetooth/module-bluez5-device.c:1811
-msgid "Bluetooth Input"
-msgstr "藍牙輸入"
-
-#: ../src/modules/bluetooth/module-bluez5-device.c:1853
+#: src/modules/bluetooth/module-bluez5-device.c:1868
msgid "High Fidelity Playback (A2DP Sink)"
msgstr "高傳真播放裝置 (A2DP Sink)"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1865
+#: src/modules/bluetooth/module-bluez5-device.c:1880
msgid "High Fidelity Capture (A2DP Source)"
msgstr "高傳真擷取裝置 (A2DP Source)"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1877
+#: src/modules/bluetooth/module-bluez5-device.c:1892
msgid "Headset Head Unit (HSP/HFP)"
msgstr "耳機麥克風頭部 (HSP/HFP)"
-#: ../src/modules/bluetooth/module-bluez5-device.c:1890
+#: src/modules/bluetooth/module-bluez5-device.c:1905
msgid "Headset Audio Gateway (HSP/HFP)"
msgstr "耳機麥克風音訊閘道 (HSP/HFP)"
-#: ../src/modules/echo-cancel/module-echo-cancel.c:61
+#: src/modules/echo-cancel/module-echo-cancel.c:59
msgid ""
"source_name=<name for the source> source_properties=<properties for the "
"source> source_master=<name of source to filter> sink_name=<name for the "
@@ -999,29 +1099,28 @@ msgstr ""
"定此模組是否要被自動載入> use_volume_sharing=<是或否> use_master_format=<是或"
"否> "
-#. add on profile
-#: ../src/modules/macosx/module-coreaudio-device.c:811
+#: src/modules/macosx/module-coreaudio-device.c:824
msgid "On"
msgstr "開"
-#: ../src/modules/module-allow-passthrough.c:73
-#: ../src/modules/module-always-sink.c:82
+#: src/modules/module-allow-passthrough.c:71
+#: src/modules/module-always-sink.c:80
msgid "Dummy Output"
msgstr "Dummy Output"
-#: ../src/modules/module-always-sink.c:36
+#: src/modules/module-always-sink.c:34
msgid "Always keeps at least one sink loaded even if it's a null one"
msgstr "即使 sink 為空的,也總是維持至少載入一個 sink"
-#: ../src/modules/module-always-source.c:37
+#: src/modules/module-always-source.c:35
msgid "Always keeps at least one source loaded even if it's a null one"
msgstr "即使來源是空的,也總是維持至少載入一個來源"
-#: ../src/modules/module-equalizer-sink.c:70
+#: src/modules/module-equalizer-sink.c:68
msgid "General Purpose Equalizer"
msgstr "通用等化器"
-#: ../src/modules/module-equalizer-sink.c:74
+#: src/modules/module-equalizer-sink.c:72
msgid ""
"sink_name=<name of the sink> sink_properties=<properties for the sink> "
"sink_master=<sink to connect to> format=<sample format> rate=<sample rate> "
@@ -1032,81 +1131,95 @@ msgstr ""
"sink> format=<取樣格式> rate=<取樣率> channels=<聲道數> channel_map=<聲道對應"
"表> autoloaded=<設定此模組是否正被自動載入> use_volume_sharing=<yes 或 no> "
-#: ../src/modules/module-equalizer-sink.c:1091
-#: ../src/modules/module-equalizer-sink.c:1214
+#: src/modules/module-equalizer-sink.c:1094
+#: src/modules/module-equalizer-sink.c:1217
#, c-format
msgid "FFT based equalizer on %s"
msgstr "FFT 基礎等化器於 %s"
-#: ../src/modules/module-filter-apply.c:49
+#: src/modules/module-filter-apply.c:47
msgid "autoclean=<automatically unload unused filters?>"
msgstr "autoclean=<是否自動取消未使用過濾器的載入?>"
-#: ../src/modules/module-ladspa-sink.c:51
+#: src/modules/module-ladspa-sink.c:50
msgid "Virtual LADSPA sink"
msgstr "虛擬 LADSPA sink"
-#: ../src/modules/module-ladspa-sink.c:55
+#: src/modules/module-ladspa-sink.c:54
+#| msgid ""
+#| "sink_name=<name for the sink> sink_properties=<properties for the sink> "
+#| "master=<name of sink to filter> sink_master=<name of sink to filter> "
+#| "format=<sample format> rate=<sample rate> channels=<number of channels> "
+#| "channel_map=<input channel map> plugin=<ladspa plugin name> label=<ladspa "
+#| "plugin label> control=<comma separated list of input control values> "
+#| "input_ladspaport_map=<comma separated list of input LADSPA port names> "
+#| "output_ladspaport_map=<comma separated list of output LADSPA port names> "
+#| "autoloaded=<set if this module is being loaded automatically> "
msgid ""
"sink_name=<name for the sink> sink_properties=<properties for the sink> "
-"master=<name of sink to filter> sink_master=<name of sink to filter> "
-"format=<sample format> rate=<sample rate> channels=<number of channels> "
-"channel_map=<input channel map> plugin=<ladspa plugin name> label=<ladspa "
-"plugin label> control=<comma separated list of input control values> "
-"input_ladspaport_map=<comma separated list of input LADSPA port names> "
-"output_ladspaport_map=<comma separated list of output LADSPA port names> "
-"autoloaded=<set if this module is being loaded automatically> "
+"sink_input_properties=<properties for the sink input> master=<name of sink "
+"to filter> sink_master=<name of sink to filter> format=<sample format> "
+"rate=<sample rate> channels=<number of channels> channel_map=<input channel "
+"map> plugin=<ladspa plugin name> label=<ladspa plugin label> control=<comma "
+"separated list of input control values> input_ladspaport_map=<comma "
+"separated list of input LADSPA port names> output_ladspaport_map=<comma "
+"separated list of output LADSPA port names> autoloaded=<set if this module "
+"is being loaded automatically> "
msgstr ""
-"sink_name=<sink 名稱> sink_properties=<sink 屬性> master=<要過濾的 sink 名稱"
+"sink_name=<sink 名稱> sink_properties=<sink 屬性> "
+"sink_input_properties=<sink 輸入屬性> master=<要過濾的 sink 名稱"
"> sink_master=<要過濾的 sink 名稱> format=<取樣格式> rate=<取樣率> "
"channel_map=<輸入聲道映射表> plugin=<ladspa 插件名稱> label=<ladspa 插件標籤"
"> control=<輸入控制值的半形逗號分隔清單> input_ladspaport_map=<輸入 LADSPA 連"
"接埠名稱的半形逗號分隔清單> output_ladspaport_map=<輸出 LADSPA 連接埠名稱的半"
"形逗號分隔清單> autoloaded=<設定此模組是否要被自動載入> "
-#: ../src/modules/module-null-sink.c:47
+#: src/modules/module-null-sink.c:46
msgid "Clocked NULL sink"
msgstr "Clocked Null sink"
-#: ../src/modules/module-null-sink.c:284
+#: src/modules/module-null-sink.c:333
msgid "Null Output"
msgstr "Null Output"
-#: ../src/modules/module-rygel-media-server.c:508
-#: ../src/modules/module-rygel-media-server.c:546
-#: ../src/modules/module-rygel-media-server.c:905
+#: src/modules/module-null-sink.c:345 src/utils/pactl.c:1058
+#, c-format
+msgid "Failed to set format: invalid format string %s"
+msgstr "未能設定格式:無效的格式字串 %s"
+
+#: src/modules/module-rygel-media-server.c:506
+#: src/modules/module-rygel-media-server.c:544
+#: src/modules/module-rygel-media-server.c:903
msgid "Output Devices"
msgstr "輸出裝置"
-#: ../src/modules/module-rygel-media-server.c:509
-#: ../src/modules/module-rygel-media-server.c:547
-#: ../src/modules/module-rygel-media-server.c:906
+#: src/modules/module-rygel-media-server.c:507
+#: src/modules/module-rygel-media-server.c:545
+#: src/modules/module-rygel-media-server.c:904
msgid "Input Devices"
msgstr "輸入裝置"
-#: ../src/modules/module-rygel-media-server.c:1063
+#: src/modules/module-rygel-media-server.c:1061
msgid "Audio on @HOSTNAME@"
msgstr "音效位於 @HOSTNAME@"
-#. TODO: old tunnel put here the remote sink_name into stream name e.g. 'Null Output for lynxis@lazus'
-#. TODO: old tunnel put here the remote source_name into stream name e.g. 'Null Output for lynxis@lazus'
-#: ../src/modules/module-tunnel-sink-new.c:309
-#: ../src/modules/module-tunnel-source-new.c:307
+#: src/modules/module-tunnel-sink-new.c:307
+#: src/modules/module-tunnel-source-new.c:305
#, c-format
msgid "Tunnel for %s@%s"
msgstr "%s@%s 的穿隧道"
-#: ../src/modules/module-tunnel-sink-new.c:532
-#: ../src/modules/module-tunnel-source-new.c:528
+#: src/modules/module-tunnel-sink-new.c:544
+#: src/modules/module-tunnel-source-new.c:540
#, c-format
msgid "Tunnel to %s/%s"
msgstr "前往 %s/%s 的穿隧道"
-#: ../src/modules/module-virtual-surround-sink.c:47
+#: src/modules/module-virtual-surround-sink.c:45
msgid "Virtual surround sink"
msgstr "虛擬環繞聲 sink"
-#: ../src/modules/module-virtual-surround-sink.c:51
+#: src/modules/module-virtual-surround-sink.c:49
msgid ""
"sink_name=<name for the sink> sink_properties=<properties for the sink> "
"master=<name of sink to filter> sink_master=<name of sink to filter> "
@@ -1121,641 +1234,648 @@ msgstr ""
"force_flat_volume=<是或否> hrir=/path/to/left_hrir.wav autoloaded=<設定此模組"
"是否自動被載入> "
-#: ../src/modules/reserve-wrap.c:149
+#: src/modules/raop/module-raop-discover.c:295
+#| msgid "Unknown error code"
+msgid "Unknown device model"
+msgstr "未知裝置型號"
+
+#: src/modules/raop/raop-sink.c:653
+msgid "RAOP standard profile"
+msgstr "RAOP 標準設定檔"
+
+#: src/modules/reserve-wrap.c:149
msgid "PulseAudio Sound Server"
msgstr "PulseAudio 音效伺服器"
-#: ../src/pulse/channelmap.c:103 ../src/pulse/channelmap.c:771
-msgid "Mono"
-msgstr "單聲道"
-
-#: ../src/pulse/channelmap.c:105
+#: src/pulse/channelmap.c:105
msgid "Front Center"
msgstr "正前方"
-#: ../src/pulse/channelmap.c:106
+#: src/pulse/channelmap.c:106
msgid "Front Left"
msgstr "左前方"
-#: ../src/pulse/channelmap.c:107
+#: src/pulse/channelmap.c:107
msgid "Front Right"
msgstr "右前方"
-#: ../src/pulse/channelmap.c:109
+#: src/pulse/channelmap.c:109
msgid "Rear Center"
msgstr "正後方"
-#: ../src/pulse/channelmap.c:110
+#: src/pulse/channelmap.c:110
msgid "Rear Left"
msgstr "左後方"
-#: ../src/pulse/channelmap.c:111
+#: src/pulse/channelmap.c:111
msgid "Rear Right"
msgstr "右後方"
-#: ../src/pulse/channelmap.c:113
+#: src/pulse/channelmap.c:113
msgid "Subwoofer"
msgstr "超低音喇叭"
-#: ../src/pulse/channelmap.c:115
+#: src/pulse/channelmap.c:115
msgid "Front Left-of-center"
msgstr "前方中央偏左"
-#: ../src/pulse/channelmap.c:116
+#: src/pulse/channelmap.c:116
msgid "Front Right-of-center"
msgstr "前方中央偏右"
-#: ../src/pulse/channelmap.c:118
+#: src/pulse/channelmap.c:118
msgid "Side Left"
msgstr "左側"
-#: ../src/pulse/channelmap.c:119
+#: src/pulse/channelmap.c:119
msgid "Side Right"
msgstr "右側"
-#: ../src/pulse/channelmap.c:121
+#: src/pulse/channelmap.c:121
msgid "Auxiliary 0"
msgstr "輔助 0"
-#: ../src/pulse/channelmap.c:122
+#: src/pulse/channelmap.c:122
msgid "Auxiliary 1"
msgstr "輔助 1"
-#: ../src/pulse/channelmap.c:123
+#: src/pulse/channelmap.c:123
msgid "Auxiliary 2"
msgstr "輔助 2"
-#: ../src/pulse/channelmap.c:124
+#: src/pulse/channelmap.c:124
msgid "Auxiliary 3"
msgstr "輔助 3"
-#: ../src/pulse/channelmap.c:125
+#: src/pulse/channelmap.c:125
msgid "Auxiliary 4"
msgstr "輔助 4"
-#: ../src/pulse/channelmap.c:126
+#: src/pulse/channelmap.c:126
msgid "Auxiliary 5"
msgstr "輔助 5"
-#: ../src/pulse/channelmap.c:127
+#: src/pulse/channelmap.c:127
msgid "Auxiliary 6"
msgstr "輔助 6"
-#: ../src/pulse/channelmap.c:128
+#: src/pulse/channelmap.c:128
msgid "Auxiliary 7"
msgstr "輔助 7"
-#: ../src/pulse/channelmap.c:129
+#: src/pulse/channelmap.c:129
msgid "Auxiliary 8"
msgstr "輔助 8"
-#: ../src/pulse/channelmap.c:130
+#: src/pulse/channelmap.c:130
msgid "Auxiliary 9"
msgstr "輔助 9"
-#: ../src/pulse/channelmap.c:131
+#: src/pulse/channelmap.c:131
msgid "Auxiliary 10"
msgstr "輔助 10"
-#: ../src/pulse/channelmap.c:132
+#: src/pulse/channelmap.c:132
msgid "Auxiliary 11"
msgstr "輔助 11"
-#: ../src/pulse/channelmap.c:133
+#: src/pulse/channelmap.c:133
msgid "Auxiliary 12"
msgstr "輔助 12"
-#: ../src/pulse/channelmap.c:134
+#: src/pulse/channelmap.c:134
msgid "Auxiliary 13"
msgstr "輔助 13"
-#: ../src/pulse/channelmap.c:135
+#: src/pulse/channelmap.c:135
msgid "Auxiliary 14"
msgstr "輔助 14"
-#: ../src/pulse/channelmap.c:136
+#: src/pulse/channelmap.c:136
msgid "Auxiliary 15"
msgstr "輔助 15"
-#: ../src/pulse/channelmap.c:137
+#: src/pulse/channelmap.c:137
msgid "Auxiliary 16"
msgstr "輔助 16"
-#: ../src/pulse/channelmap.c:138
+#: src/pulse/channelmap.c:138
msgid "Auxiliary 17"
msgstr "輔助 17"
-#: ../src/pulse/channelmap.c:139
+#: src/pulse/channelmap.c:139
msgid "Auxiliary 18"
msgstr "輔助 18"
-#: ../src/pulse/channelmap.c:140
+#: src/pulse/channelmap.c:140
msgid "Auxiliary 19"
msgstr "輔助 19"
-#: ../src/pulse/channelmap.c:141
+#: src/pulse/channelmap.c:141
msgid "Auxiliary 20"
msgstr "輔助 20"
-#: ../src/pulse/channelmap.c:142
+#: src/pulse/channelmap.c:142
msgid "Auxiliary 21"
msgstr "輔助 21"
-#: ../src/pulse/channelmap.c:143
+#: src/pulse/channelmap.c:143
msgid "Auxiliary 22"
msgstr "輔助 22"
-#: ../src/pulse/channelmap.c:144
+#: src/pulse/channelmap.c:144
msgid "Auxiliary 23"
msgstr "輔助 23"
-#: ../src/pulse/channelmap.c:145
+#: src/pulse/channelmap.c:145
msgid "Auxiliary 24"
msgstr "輔助 24"
-#: ../src/pulse/channelmap.c:146
+#: src/pulse/channelmap.c:146
msgid "Auxiliary 25"
msgstr "輔助 25"
-#: ../src/pulse/channelmap.c:147
+#: src/pulse/channelmap.c:147
msgid "Auxiliary 26"
msgstr "輔助 26"
-#: ../src/pulse/channelmap.c:148
+#: src/pulse/channelmap.c:148
msgid "Auxiliary 27"
msgstr "輔助 27"
-#: ../src/pulse/channelmap.c:149
+#: src/pulse/channelmap.c:149
msgid "Auxiliary 28"
msgstr "輔助 28"
-#: ../src/pulse/channelmap.c:150
+#: src/pulse/channelmap.c:150
msgid "Auxiliary 29"
msgstr "輔助 29"
-#: ../src/pulse/channelmap.c:151
+#: src/pulse/channelmap.c:151
msgid "Auxiliary 30"
msgstr "輔助 30"
-#: ../src/pulse/channelmap.c:152
+#: src/pulse/channelmap.c:152
msgid "Auxiliary 31"
msgstr "輔助 31"
-#: ../src/pulse/channelmap.c:154
+#: src/pulse/channelmap.c:154
msgid "Top Center"
msgstr "正上方"
-#: ../src/pulse/channelmap.c:156
+#: src/pulse/channelmap.c:156
msgid "Top Front Center"
msgstr "頂端正上方"
-#: ../src/pulse/channelmap.c:157
+#: src/pulse/channelmap.c:157
msgid "Top Front Left"
msgstr "頂端左前方"
-#: ../src/pulse/channelmap.c:158
+#: src/pulse/channelmap.c:158
msgid "Top Front Right"
msgstr "頂端右前方"
-#: ../src/pulse/channelmap.c:160
+#: src/pulse/channelmap.c:160
msgid "Top Rear Center"
msgstr "頂端正後方"
-#: ../src/pulse/channelmap.c:161
+#: src/pulse/channelmap.c:161
msgid "Top Rear Left"
msgstr "頂端左後方"
-#: ../src/pulse/channelmap.c:162
+#: src/pulse/channelmap.c:162
msgid "Top Rear Right"
msgstr "頂端右後方"
-#: ../src/pulse/channelmap.c:479 ../src/pulse/format.c:121
-#: ../src/pulse/sample.c:177 ../src/pulse/volume.c:306
-#: ../src/pulse/volume.c:332 ../src/pulse/volume.c:352
-#: ../src/pulse/volume.c:384 ../src/pulse/volume.c:424
-#: ../src/pulse/volume.c:443
+#: src/pulse/channelmap.c:479 src/pulse/format.c:123 src/pulse/sample.c:177
+#: src/pulse/volume.c:306 src/pulse/volume.c:332 src/pulse/volume.c:352
+#: src/pulse/volume.c:384 src/pulse/volume.c:424 src/pulse/volume.c:443
msgid "(invalid)"
msgstr "(無效)"
-#: ../src/pulse/channelmap.c:780
+#: src/pulse/channelmap.c:780
msgid "Surround 4.0"
msgstr "環繞聲 4.0"
-#: ../src/pulse/channelmap.c:786
+#: src/pulse/channelmap.c:786
msgid "Surround 4.1"
msgstr "環繞聲 4.1"
-#: ../src/pulse/channelmap.c:792
+#: src/pulse/channelmap.c:792
msgid "Surround 5.0"
msgstr "環繞聲 5.0"
-#: ../src/pulse/channelmap.c:798
+#: src/pulse/channelmap.c:798
msgid "Surround 5.1"
msgstr "環繞聲 5.1"
-#: ../src/pulse/channelmap.c:805
+#: src/pulse/channelmap.c:805
msgid "Surround 7.1"
msgstr "環繞聲 7.1"
-#: ../src/pulse/client-conf-x11.c:53 ../src/utils/pax11publish.c:97
+#: src/pulse/client-conf-x11.c:61 src/utils/pax11publish.c:97
msgid "xcb_connect() failed"
msgstr "xcb_connect() 失敗"
-#: ../src/pulse/client-conf-x11.c:58 ../src/utils/pax11publish.c:102
+#: src/pulse/client-conf-x11.c:66 src/utils/pax11publish.c:102
msgid "xcb_connection_has_error() returned true"
msgstr "xcb_connection_has_error() 傳回真值"
-#: ../src/pulse/client-conf-x11.c:94
+#: src/pulse/client-conf-x11.c:102
msgid "Failed to parse cookie data"
msgstr "未能解析 cookie 資料"
-#: ../src/pulse/context.c:702
+#: src/pulse/context.c:706
#, c-format
msgid "fork(): %s"
msgstr "fork():%s"
-#: ../src/pulse/context.c:757
+#: src/pulse/context.c:761
#, c-format
msgid "waitpid(): %s"
msgstr "waitpid():%s"
-#: ../src/pulse/context.c:1463
+#: src/pulse/context.c:1467
#, c-format
msgid "Received message for unknown extension '%s'"
msgstr "已接收到未知擴展功能的訊息「%s」"
-#: ../src/pulse/direction.c:37
+#: src/pulse/direction.c:37
msgid "input"
msgstr "輸入"
-#: ../src/pulse/direction.c:39
+#: src/pulse/direction.c:39
msgid "output"
msgstr "輸出"
-#: ../src/pulse/direction.c:41
+#: src/pulse/direction.c:41
msgid "bidirectional"
msgstr "雙向"
-#: ../src/pulse/direction.c:43
+#: src/pulse/direction.c:43
msgid "invalid"
msgstr "無效"
-#: ../src/pulsecore/core-util.c:1856
+#: src/pulsecore/core-util.c:1712
#, c-format
+#| msgid ""
+#| "XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! (This "
+#| "could e g happen if you try to connect to a non-root PulseAudio as a root "
+#| "user, over the native protocol. Don't do that.)"
msgid ""
"XDG_RUNTIME_DIR (%s) is not owned by us (uid %d), but by uid %d! (This could "
-"e g happen if you try to connect to a non-root PulseAudio as a root user, "
+"e.g. happen if you try to connect to a non-root PulseAudio as a root user, "
"over the native protocol. Don't do that.)"
msgstr ""
"XDG_RUNTIME_DIR (%s) 並非為我們 (uid %d) 所有,擁有者實為 uid %d!(如果您試圖"
"以 root 使用者身份、透過原生協定連接到非 root PulseAudio 的話有可能發生這種狀"
"況。請不要這麼做。)"
-#: ../src/pulsecore/core-util.h:97
+#: src/pulsecore/core-util.h:96
msgid "yes"
msgstr "是"
-#: ../src/pulsecore/core-util.h:97
+#: src/pulsecore/core-util.h:96
msgid "no"
msgstr "否"
-#: ../src/pulsecore/lock-autospawn.c:141 ../src/pulsecore/lock-autospawn.c:227
+#: src/pulsecore/lock-autospawn.c:141 src/pulsecore/lock-autospawn.c:227
msgid "Cannot access autospawn lock."
msgstr "無法存取 autospawn 鎖。"
-#: ../src/pulsecore/log.c:165
+#: src/pulsecore/log.c:165
#, c-format
msgid "Failed to open target file '%s'."
msgstr "無法開啟目標檔「%s」。"
-#: ../src/pulsecore/log.c:188
+#: src/pulsecore/log.c:188
#, c-format
msgid ""
"Tried to open target file '%s', '%s.1', '%s.2' ... '%s.%d', but all failed."
msgstr "試圖開啟目標檔「%s」、「%s.1」、「%s.2」...「%s.%d」,但全都失敗。"
-#: ../src/pulsecore/log.c:651
+#: src/pulsecore/log.c:651
msgid "Invalid log target."
msgstr "無效的紀錄目標。"
-#: ../src/pulsecore/sink.c:3490
+#: src/pulsecore/sink.c:3524
msgid "Built-in Audio"
msgstr "內部音效"
-#: ../src/pulsecore/sink.c:3495
+#: src/pulsecore/sink.c:3529
msgid "Modem"
msgstr "數據機"
-#: ../src/pulse/error.c:38
+#: src/pulse/error.c:38
msgid "OK"
msgstr "確定"
-#: ../src/pulse/error.c:39
+#: src/pulse/error.c:39
msgid "Access denied"
msgstr "拒絕存取"
-#: ../src/pulse/error.c:40
+#: src/pulse/error.c:40
msgid "Unknown command"
msgstr "未知指令"
-#: ../src/pulse/error.c:41
+#: src/pulse/error.c:41
msgid "Invalid argument"
msgstr "無效的參數"
-#: ../src/pulse/error.c:42
+#: src/pulse/error.c:42
msgid "Entity exists"
msgstr "實體存在"
-#: ../src/pulse/error.c:43
+#: src/pulse/error.c:43
msgid "No such entity"
msgstr "無此實體"
-#: ../src/pulse/error.c:44
+#: src/pulse/error.c:44
msgid "Connection refused"
msgstr "拒絕連線"
-#: ../src/pulse/error.c:45
+#: src/pulse/error.c:45
msgid "Protocol error"
msgstr "協定錯誤"
-#: ../src/pulse/error.c:46
+#: src/pulse/error.c:46
msgid "Timeout"
msgstr "逾時"
-#: ../src/pulse/error.c:47
+#: src/pulse/error.c:47
msgid "No authentication key"
msgstr "無認證金鑰"
-#: ../src/pulse/error.c:48
+#: src/pulse/error.c:48
msgid "Internal error"
msgstr "內部錯誤"
-#: ../src/pulse/error.c:49
+#: src/pulse/error.c:49
msgid "Connection terminated"
msgstr "連線已終止"
-#: ../src/pulse/error.c:50
+#: src/pulse/error.c:50
msgid "Entity killed"
msgstr "實體已結束"
-#: ../src/pulse/error.c:51
+#: src/pulse/error.c:51
msgid "Invalid server"
msgstr "無效的伺服器"
-#: ../src/pulse/error.c:52
+#: src/pulse/error.c:52
msgid "Module initialization failed"
msgstr "模組初始化失敗"
-#: ../src/pulse/error.c:53
+#: src/pulse/error.c:53
msgid "Bad state"
msgstr "不良狀態"
-#: ../src/pulse/error.c:54
+#: src/pulse/error.c:54
msgid "No data"
msgstr "無資料"
-#: ../src/pulse/error.c:55
+#: src/pulse/error.c:55
msgid "Incompatible protocol version"
msgstr "不相容的協定版本"
-#: ../src/pulse/error.c:56
+#: src/pulse/error.c:56
msgid "Too large"
msgstr "過大"
-#: ../src/pulse/error.c:57
+#: src/pulse/error.c:57
msgid "Not supported"
msgstr "不支援"
-#: ../src/pulse/error.c:58
+#: src/pulse/error.c:58
msgid "Unknown error code"
msgstr "未知的錯誤碼"
-#: ../src/pulse/error.c:59
+#: src/pulse/error.c:59
msgid "No such extension"
msgstr "無此擴展功能"
-#: ../src/pulse/error.c:60
+#: src/pulse/error.c:60
msgid "Obsolete functionality"
msgstr "淘汰的功能"
-#: ../src/pulse/error.c:61
+#: src/pulse/error.c:61
msgid "Missing implementation"
msgstr "遺失的實作"
-#: ../src/pulse/error.c:62
+#: src/pulse/error.c:62
msgid "Client forked"
msgstr "客戶端已分支"
-#: ../src/pulse/error.c:63
+#: src/pulse/error.c:63
msgid "Input/Output error"
msgstr "輸入/輸出 錯誤"
-#: ../src/pulse/error.c:64
+#: src/pulse/error.c:64
msgid "Device or resource busy"
msgstr "裝置或資源忙碌"
-#: ../src/pulse/sample.c:179
+#: src/pulse/sample.c:179
#, c-format
msgid "%s %uch %uHz"
msgstr "%s %uch %uHz"
-#: ../src/pulse/sample.c:191
+#: src/pulse/sample.c:191
#, c-format
msgid "%0.1f GiB"
msgstr "%0.1f GiB"
-#: ../src/pulse/sample.c:193
+#: src/pulse/sample.c:193
#, c-format
msgid "%0.1f MiB"
msgstr "%0.1f MiB"
-#: ../src/pulse/sample.c:195
+#: src/pulse/sample.c:195
#, c-format
msgid "%0.1f KiB"
msgstr "%0.1f KiB"
-#: ../src/pulse/sample.c:197
+#: src/pulse/sample.c:197
#, c-format
msgid "%u B"
msgstr "%u B"
-#: ../src/utils/pacat.c:134
+#: src/utils/pacat.c:134
#, c-format
msgid "Failed to drain stream: %s"
msgstr "未能排出串流:%s"
-#: ../src/utils/pacat.c:139
+#: src/utils/pacat.c:139
msgid "Playback stream drained."
msgstr "播放控制串流已排出。"
-#: ../src/utils/pacat.c:150
+#: src/utils/pacat.c:150
msgid "Draining connection to server."
msgstr "正在排出連線到伺服器。"
-#: ../src/utils/pacat.c:163
+#: src/utils/pacat.c:163
#, c-format
msgid "pa_stream_drain(): %s"
msgstr "pa_stream_drain():%s"
-#: ../src/utils/pacat.c:194 ../src/utils/pacat.c:543
+#: src/utils/pacat.c:194 src/utils/pacat.c:543
#, c-format
msgid "pa_stream_begin_write() failed: %s"
msgstr "pa_stream_begin_write() 失敗:%s"
-#: ../src/utils/pacat.c:244 ../src/utils/pacat.c:274
+#: src/utils/pacat.c:244 src/utils/pacat.c:274
#, c-format
msgid "pa_stream_peek() failed: %s"
msgstr "pa_stream_peek() 失敗:%s"
-#: ../src/utils/pacat.c:324
+#: src/utils/pacat.c:324
msgid "Stream successfully created."
msgstr "已成功建立串流。"
-#: ../src/utils/pacat.c:327
+#: src/utils/pacat.c:327
#, c-format
msgid "pa_stream_get_buffer_attr() failed: %s"
msgstr "pa_stream_get_buffer_attr() 失敗:%s"
-#: ../src/utils/pacat.c:331
+#: src/utils/pacat.c:331
#, c-format
msgid "Buffer metrics: maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
msgstr "緩衝矩陣:maxlength=%u, tlength=%u, prebuf=%u, minreq=%u"
-#: ../src/utils/pacat.c:334
+#: src/utils/pacat.c:334
#, c-format
msgid "Buffer metrics: maxlength=%u, fragsize=%u"
msgstr "緩衝矩陣:maxlength=%u, fragsize=%u"
-#: ../src/utils/pacat.c:338
+#: src/utils/pacat.c:338
#, c-format
msgid "Using sample spec '%s', channel map '%s'."
msgstr "使用取樣規格「%s」,聲道對應表「%s」"
-#: ../src/utils/pacat.c:342
+#: src/utils/pacat.c:342
#, c-format
msgid "Connected to device %s (index: %u, suspended: %s)."
msgstr "已連接到裝置 %s(索引:%u,已暫停:%s)。"
-#: ../src/utils/pacat.c:352
+#: src/utils/pacat.c:352
#, c-format
msgid "Stream error: %s"
msgstr "串流錯誤:%s"
-#: ../src/utils/pacat.c:362
+#: src/utils/pacat.c:362
#, c-format
msgid "Stream device suspended.%s"
msgstr "串流裝置已暫停。%s"
-#: ../src/utils/pacat.c:364
+#: src/utils/pacat.c:364
#, c-format
msgid "Stream device resumed.%s"
msgstr "串流裝置已恢復。%s"
-#: ../src/utils/pacat.c:372
+#: src/utils/pacat.c:372
#, c-format
msgid "Stream underrun.%s"
msgstr "串流欠載運行。%s"
-#: ../src/utils/pacat.c:379
+#: src/utils/pacat.c:379
#, c-format
msgid "Stream overrun.%s"
msgstr "串流超載運行。%s"
-#: ../src/utils/pacat.c:386
+#: src/utils/pacat.c:386
#, c-format
msgid "Stream started.%s"
msgstr "串流已開始。%s"
-#: ../src/utils/pacat.c:393
+#: src/utils/pacat.c:393
#, c-format
msgid "Stream moved to device %s (%u, %ssuspended).%s"
msgstr "串流移至裝置 %s(%u,%s已暫停)。%s"
-#: ../src/utils/pacat.c:393
+#: src/utils/pacat.c:393
msgid "not "
msgstr "不是"
-#: ../src/utils/pacat.c:400
+#: src/utils/pacat.c:400
#, c-format
msgid "Stream buffer attributes changed.%s"
msgstr "串流緩衝特徵已變更。%s"
-#: ../src/utils/pacat.c:415
+#: src/utils/pacat.c:415
msgid "Cork request stack is empty: corking stream"
msgstr "Cork 請求堆疊為空:corking 串流"
-#: ../src/utils/pacat.c:421
+#: src/utils/pacat.c:421
msgid "Cork request stack is empty: uncorking stream"
msgstr "Cork 請求堆疊為空:uncorking 串流"
-#: ../src/utils/pacat.c:425
+#: src/utils/pacat.c:425
msgid "Warning: Received more uncork requests than cork requests."
msgstr "警告:已接收到多於 cork 請求的 uncork 請求。"
-#: ../src/utils/pacat.c:450
+#: src/utils/pacat.c:450
#, c-format
msgid "Connection established.%s"
msgstr "連線已建立。%s"
-#: ../src/utils/pacat.c:453
+#: src/utils/pacat.c:453
#, c-format
msgid "pa_stream_new() failed: %s"
msgstr "pa_stream_new() 失敗:%s"
-#: ../src/utils/pacat.c:491
+#: src/utils/pacat.c:491
#, c-format
msgid "pa_stream_connect_playback() failed: %s"
msgstr "pa_stream_connect_playback() 失敗:%s"
-#: ../src/utils/pacat.c:497
+#: src/utils/pacat.c:497
#, c-format
msgid "Failed to set monitor stream: %s"
msgstr "無法設定監聽器串流:%s"
-#: ../src/utils/pacat.c:501
+#: src/utils/pacat.c:501
#, c-format
msgid "pa_stream_connect_record() failed: %s"
msgstr "pa_stream_connect_record() 失敗:%s"
-#: ../src/utils/pacat.c:514 ../src/utils/pactl.c:1446
+#: src/utils/pacat.c:514 src/utils/pactl.c:1454
#, c-format
msgid "Connection failure: %s"
msgstr "連線失敗:%s"
-#: ../src/utils/pacat.c:557
+#: src/utils/pacat.c:557
msgid "Got EOF."
msgstr "已取得 EOF。"
-#: ../src/utils/pacat.c:581
+#: src/utils/pacat.c:581
#, c-format
msgid "pa_stream_write() failed: %s"
msgstr "pa_stream_write() failed:%s"
-#: ../src/utils/pacat.c:605
+#: src/utils/pacat.c:605
#, c-format
msgid "write() failed: %s"
msgstr "write() 失敗:%s"
-#: ../src/utils/pacat.c:626
+#: src/utils/pacat.c:626
msgid "Got signal, exiting."
msgstr "已取得訊號,正在退出。"
-#: ../src/utils/pacat.c:640
+#: src/utils/pacat.c:640
#, c-format
msgid "Failed to get latency: %s"
msgstr "未能取得傳輸延遲:%s"
-#: ../src/utils/pacat.c:645
+#: src/utils/pacat.c:645
#, c-format
msgid "Time: %0.3f sec; Latency: %0.0f usec."
msgstr "時間:%0.3f 秒;延遲:%0.0f 微秒。"
-#: ../src/utils/pacat.c:666
+#: src/utils/pacat.c:666
#, c-format
msgid "pa_stream_update_timing_info() failed: %s"
msgstr "pa_stream_update_timing_info() 失敗:%s"
-#: ../src/utils/pacat.c:676
+#: src/utils/pacat.c:676
#, c-format
msgid ""
"%s [options]\n"
@@ -1868,28 +1988,28 @@ msgstr ""
" --list-file-formats 列出可用的檔案格式。\n"
" --monitor-stream=INDEX 從 sink 輸入以索引 INDEX 錄製。\n"
-#: ../src/utils/pacat.c:793
+#: src/utils/pacat.c:793
msgid "Play back encoded audio files on a PulseAudio sound server."
msgstr "在 PulseAudio 音效伺服器回放編碼音訊檔案。"
-#: ../src/utils/pacat.c:797
+#: src/utils/pacat.c:797
msgid ""
"Capture audio data from a PulseAudio sound server and write it to a file."
msgstr "從 PulseAudio 音效伺服器捕捉音訊資料並寫入檔案中。"
-#: ../src/utils/pacat.c:801
+#: src/utils/pacat.c:801
msgid ""
"Capture audio data from a PulseAudio sound server and write it to STDOUT or "
"the specified file."
msgstr "從 PulseAudio 音效伺服器捕捉音訊資料並寫入 STDOUT 或指定檔案中。"
-#: ../src/utils/pacat.c:805
+#: src/utils/pacat.c:805
msgid ""
"Play back audio data from STDIN or the specified file on a PulseAudio sound "
"server."
msgstr "在 PulseAudio 音效伺服器回放取自 STDIN 的音訊資料或指定的檔案。"
-#: ../src/utils/pacat.c:819
+#: src/utils/pacat.c:819
#, c-format
msgid ""
"pacat %s\n"
@@ -1900,226 +2020,226 @@ msgstr ""
"以 libpulse %s 編譯\n"
"以 libpulse %s 連結\n"
-#: ../src/utils/pacat.c:852 ../src/utils/pactl.c:1648
+#: src/utils/pacat.c:852 src/utils/pactl.c:1656
#, c-format
msgid "Invalid client name '%s'"
msgstr "無效的客戶端名稱「%s」"
-#: ../src/utils/pacat.c:867
+#: src/utils/pacat.c:867
#, c-format
msgid "Invalid stream name '%s'"
msgstr "無效的串流名稱「%s」"
-#: ../src/utils/pacat.c:904
+#: src/utils/pacat.c:904
#, c-format
msgid "Invalid channel map '%s'"
msgstr "無效的聲道對應表「%s」"
-#: ../src/utils/pacat.c:933 ../src/utils/pacat.c:947
+#: src/utils/pacat.c:933 src/utils/pacat.c:947
#, c-format
msgid "Invalid latency specification '%s'"
msgstr "無效的延遲規格「%s」"
-#: ../src/utils/pacat.c:940 ../src/utils/pacat.c:954
+#: src/utils/pacat.c:940 src/utils/pacat.c:954
#, c-format
msgid "Invalid process time specification '%s'"
msgstr "無效的程序時間規格「%s」"
-#: ../src/utils/pacat.c:966
+#: src/utils/pacat.c:966
#, c-format
msgid "Invalid property '%s'"
msgstr "無效的屬性「%s」"
-#: ../src/utils/pacat.c:985
+#: src/utils/pacat.c:985
#, c-format
msgid "Unknown file format %s."
msgstr "未知檔案格式 %s。"
-#: ../src/utils/pacat.c:1000
+#: src/utils/pacat.c:1000
msgid "Failed to parse the argument for --monitor-stream"
msgstr "無法解析 --monitor-stream 的引數"
-#: ../src/utils/pacat.c:1011
+#: src/utils/pacat.c:1011
msgid "Invalid sample specification"
msgstr "無效的取樣規格"
-#: ../src/utils/pacat.c:1021
+#: src/utils/pacat.c:1021
#, c-format
msgid "open(): %s"
msgstr "open():%s"
-#: ../src/utils/pacat.c:1026
+#: src/utils/pacat.c:1026
#, c-format
msgid "dup2(): %s"
msgstr "dup2():%s"
-#: ../src/utils/pacat.c:1033
+#: src/utils/pacat.c:1033
msgid "Too many arguments."
msgstr "太多參數。"
-#: ../src/utils/pacat.c:1044
+#: src/utils/pacat.c:1044
msgid "Failed to generate sample specification for file."
msgstr "未能替檔案產生取樣規格。"
-#: ../src/utils/pacat.c:1070
+#: src/utils/pacat.c:1070
msgid "Failed to open audio file."
msgstr "未能開啟音效檔。"
-#: ../src/utils/pacat.c:1076
+#: src/utils/pacat.c:1076
msgid ""
"Warning: specified sample specification will be overwritten with "
"specification from file."
msgstr "警告:指定的取樣規格將會覆寫從檔案得到的規格。"
-#: ../src/utils/pacat.c:1079 ../src/utils/pactl.c:1712
+#: src/utils/pacat.c:1079 src/utils/pactl.c:1720
msgid "Failed to determine sample specification from file."
msgstr "未能從檔案得知取樣規格。"
-#: ../src/utils/pacat.c:1088
+#: src/utils/pacat.c:1088
msgid "Warning: Failed to determine channel map from file."
msgstr "警告:未能從檔案取得聲道對應表。"
-#: ../src/utils/pacat.c:1099
+#: src/utils/pacat.c:1099
msgid "Channel map doesn't match sample specification"
msgstr "聲道對應表與取樣規格不符"
-#: ../src/utils/pacat.c:1110
+#: src/utils/pacat.c:1110
msgid "Warning: failed to write channel map to file."
msgstr "警告:未能將聲道對應表寫入檔案。"
-#: ../src/utils/pacat.c:1125
+#: src/utils/pacat.c:1125
#, c-format
msgid ""
"Opening a %s stream with sample specification '%s' and channel map '%s'."
msgstr "正在開啟一道 %s 串流,取樣規格為「%s」,聲道對應表為「%s」。"
-#: ../src/utils/pacat.c:1126
+#: src/utils/pacat.c:1126
msgid "recording"
msgstr "錄製中"
-#: ../src/utils/pacat.c:1126
+#: src/utils/pacat.c:1126
msgid "playback"
msgstr "播放控制"
-#: ../src/utils/pacat.c:1150
+#: src/utils/pacat.c:1150
msgid "Failed to set media name."
msgstr "未能設定媒體名稱。"
-#: ../src/utils/pacat.c:1160 ../src/utils/pactl.c:2062
+#: src/utils/pacat.c:1160 src/utils/pactl.c:2070
msgid "pa_mainloop_new() failed."
msgstr "pa_mainloop_new() 失敗。"
-#: ../src/utils/pacat.c:1183
+#: src/utils/pacat.c:1183
msgid "io_new() failed."
msgstr "io_new() 失敗。"
-#: ../src/utils/pacat.c:1190 ../src/utils/pactl.c:2074
+#: src/utils/pacat.c:1190 src/utils/pactl.c:2082
msgid "pa_context_new() failed."
msgstr "pa_context_new() 失敗。"
-#: ../src/utils/pacat.c:1198 ../src/utils/pactl.c:2080
+#: src/utils/pacat.c:1198 src/utils/pactl.c:2088
#, c-format
msgid "pa_context_connect() failed: %s"
msgstr "pa_context_connect() 失敗:%s"
-#: ../src/utils/pacat.c:1204
+#: src/utils/pacat.c:1204
msgid "pa_context_rttime_new() failed."
msgstr "pa_context_rttime_new() 失敗。"
-#: ../src/utils/pacat.c:1211 ../src/utils/pactl.c:2085
+#: src/utils/pacat.c:1211 src/utils/pactl.c:2093
msgid "pa_mainloop_run() failed."
msgstr "pa_mainloop_run() 失敗。"
-#: ../src/utils/pacmd.c:51 ../src/utils/pactl.c:1570
+#: src/utils/pacmd.c:51 src/utils/pactl.c:1578
msgid "NAME [ARGS ...]"
msgstr "NAME [ARGS ...]"
-#: ../src/utils/pacmd.c:52 ../src/utils/pacmd.c:60 ../src/utils/pactl.c:1571
+#: src/utils/pacmd.c:52 src/utils/pacmd.c:60 src/utils/pactl.c:1579
msgid "NAME|#N"
msgstr "NAME|#N"
-#: ../src/utils/pacmd.c:53 ../src/utils/pacmd.c:63 ../src/utils/pactl.c:1569
-#: ../src/utils/pactl.c:1575
+#: src/utils/pacmd.c:53 src/utils/pacmd.c:63 src/utils/pactl.c:1577
+#: src/utils/pactl.c:1583
msgid "NAME"
msgstr "NAME"
-#: ../src/utils/pacmd.c:54
+#: src/utils/pacmd.c:54
msgid "NAME|#N VOLUME"
msgstr "NAME|#N VOLUME"
-#: ../src/utils/pacmd.c:55
+#: src/utils/pacmd.c:55
msgid "#N VOLUME"
msgstr "#N VOLUME"
-#: ../src/utils/pacmd.c:56 ../src/utils/pacmd.c:70 ../src/utils/pactl.c:1573
+#: src/utils/pacmd.c:56 src/utils/pacmd.c:70 src/utils/pactl.c:1581
msgid "NAME|#N 1|0"
msgstr "NAME|#N 1|0"
-#: ../src/utils/pacmd.c:57
+#: src/utils/pacmd.c:57
msgid "#N 1|0"
msgstr "#N 1|0"
-#: ../src/utils/pacmd.c:58
+#: src/utils/pacmd.c:58
msgid "NAME|#N KEY=VALUE"
msgstr "NAME|#N KEY=VALUE"
-#: ../src/utils/pacmd.c:59
+#: src/utils/pacmd.c:59
msgid "#N KEY=VALUE"
msgstr "#N KEY=VALUE"
-#: ../src/utils/pacmd.c:61
+#: src/utils/pacmd.c:61
msgid "#N"
msgstr "#N"
-#: ../src/utils/pacmd.c:62
+#: src/utils/pacmd.c:62
msgid "NAME SINK|#N"
msgstr "NAME SINK|#N"
-#: ../src/utils/pacmd.c:64 ../src/utils/pacmd.c:65
+#: src/utils/pacmd.c:64 src/utils/pacmd.c:65
msgid "NAME FILENAME"
msgstr "NAME FILENAME"
-#: ../src/utils/pacmd.c:66
+#: src/utils/pacmd.c:66
msgid "PATHNAME"
msgstr "PATHNAME"
-#: ../src/utils/pacmd.c:67
+#: src/utils/pacmd.c:67
msgid "FILENAME SINK|#N"
msgstr "FILENAME SINK|#N"
-#: ../src/utils/pacmd.c:69 ../src/utils/pactl.c:1572
+#: src/utils/pacmd.c:69 src/utils/pactl.c:1580
msgid "#N SINK|SOURCE"
msgstr "#N SINK|SOURCE"
-#: ../src/utils/pacmd.c:71 ../src/utils/pacmd.c:77 ../src/utils/pacmd.c:78
+#: src/utils/pacmd.c:71 src/utils/pacmd.c:77 src/utils/pacmd.c:78
msgid "1|0"
msgstr "1|0"
-#: ../src/utils/pacmd.c:72 ../src/utils/pactl.c:1574
+#: src/utils/pacmd.c:72 src/utils/pactl.c:1582
msgid "CARD PROFILE"
msgstr "CARD PROFILE"
-#: ../src/utils/pacmd.c:73 ../src/utils/pactl.c:1576
+#: src/utils/pacmd.c:73 src/utils/pactl.c:1584
msgid "NAME|#N PORT"
msgstr "NAME|#N PORT"
-#: ../src/utils/pacmd.c:74 ../src/utils/pactl.c:1582
+#: src/utils/pacmd.c:74 src/utils/pactl.c:1590
msgid "CARD-NAME|CARD-#N PORT OFFSET"
msgstr "CARD-NAME|CARD-#N PORT OFFSET"
-#: ../src/utils/pacmd.c:75
+#: src/utils/pacmd.c:75
msgid "TARGET"
msgstr "TARGET"
-#: ../src/utils/pacmd.c:76
+#: src/utils/pacmd.c:76
msgid "NUMERIC-LEVEL"
msgstr "NUMERIC-LEVEL"
-#: ../src/utils/pacmd.c:79
+#: src/utils/pacmd.c:79
msgid "FRAMES"
msgstr "FRAMES"
-#: ../src/utils/pacmd.c:81
+#: src/utils/pacmd.c:81
#, c-format
msgid ""
"\n"
@@ -2132,7 +2252,7 @@ msgstr ""
" --version 顯示版本\n"
"當沒有給予指令時,pacmd 會以互動模式啟動。\n"
-#: ../src/utils/pacmd.c:128
+#: src/utils/pacmd.c:128
#, c-format
msgid ""
"pacmd %s\n"
@@ -2143,69 +2263,75 @@ msgstr ""
"配合 libpulse %s 編譯\n"
"已與 libpulse %s 連結\n"
-#: ../src/utils/pacmd.c:142
+#: src/utils/pacmd.c:142
msgid "No PulseAudio daemon running, or not running as session daemon."
msgstr "無 PulseAudio 幕後程式正執行中,或者未以作業階段幕後程式執行中。"
-#: ../src/utils/pacmd.c:147
+#: src/utils/pacmd.c:147
#, c-format
msgid "socket(PF_UNIX, SOCK_STREAM, 0): %s"
msgstr "socket(PF_UNIX, SOCK_STREAM, 0):%s"
-#: ../src/utils/pacmd.c:164
+#: src/utils/pacmd.c:164
#, c-format
msgid "connect(): %s"
msgstr "connect():%s"
-#: ../src/utils/pacmd.c:172
+#: src/utils/pacmd.c:172
msgid "Failed to kill PulseAudio daemon."
msgstr "未能終止 PulseAudio 幕後程式。"
-#: ../src/utils/pacmd.c:180
+#: src/utils/pacmd.c:180
msgid "Daemon not responding."
msgstr "幕後程式沒有回應。"
-#: ../src/utils/pacmd.c:212 ../src/utils/pacmd.c:321 ../src/utils/pacmd.c:339
+#: src/utils/pacmd.c:212 src/utils/pacmd.c:321 src/utils/pacmd.c:339
#, c-format
msgid "write(): %s"
msgstr "write():%s"
-#: ../src/utils/pacmd.c:268
+#: src/utils/pacmd.c:268
#, c-format
msgid "poll(): %s"
msgstr "poll():%s"
-#: ../src/utils/pacmd.c:279 ../src/utils/pacmd.c:299
+#: src/utils/pacmd.c:279 src/utils/pacmd.c:299
#, c-format
msgid "read(): %s"
msgstr "read():%s"
-#: ../src/utils/pactl.c:164
+#: src/utils/pactl.c:164
#, c-format
msgid "Failed to get statistics: %s"
msgstr "未能取得統計:%s"
-#: ../src/utils/pactl.c:170
+#: src/utils/pactl.c:170
#, c-format
-msgid "Currently in use: %u blocks containing %s bytes total.\n"
-msgstr "目前使用中:%u 個區塊共包含 %s bytes。\n"
+#| msgid "Currently in use: %u blocks containing %s bytes total.\n"
+msgid "Currently in use: %u block containing %s bytes total.\n"
+msgid_plural "Currently in use: %u blocks containing %s bytes total.\n"
+msgstr[0] "目前使用中:%u 個區塊共包含 %s bytes。\n"
-#: ../src/utils/pactl.c:173
+#: src/utils/pactl.c:176
#, c-format
-msgid "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
-msgstr "在整個生命週期間分配:%u 個區塊共包含 %s bytes。\n"
+#| msgid ""
+#| "Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgid "Allocated during whole lifetime: %u block containing %s bytes total.\n"
+msgid_plural ""
+"Allocated during whole lifetime: %u blocks containing %s bytes total.\n"
+msgstr[0] "在整個生命週期間分配:%u 個區塊共包含 %s bytes。\n"
-#: ../src/utils/pactl.c:176
+#: src/utils/pactl.c:182
#, c-format
msgid "Sample cache size: %s\n"
msgstr "取樣快取大小:%s\n"
-#: ../src/utils/pactl.c:185
+#: src/utils/pactl.c:191
#, c-format
msgid "Failed to get server information: %s"
msgstr "未能取得伺服器資訊:%s"
-#: ../src/utils/pactl.c:190
+#: src/utils/pactl.c:196
#, c-format
msgid ""
"Server String: %s\n"
@@ -2222,7 +2348,7 @@ msgstr ""
"客戶端索引:%u\n"
"Tile 大小:%zu\n"
-#: ../src/utils/pactl.c:206
+#: src/utils/pactl.c:212
#, c-format
msgid ""
"User Name: %s\n"
@@ -2245,12 +2371,12 @@ msgstr ""
"預設來源:%s\n"
"Cookie:%04x:%04x\n"
-#: ../src/utils/pactl.c:255 ../src/utils/pactl.c:900 ../src/utils/pactl.c:978
+#: src/utils/pactl.c:261 src/utils/pactl.c:908 src/utils/pactl.c:986
#, c-format
msgid "Failed to get sink information: %s"
msgstr "未能取得 sink 資訊:%s"
-#: ../src/utils/pactl.c:281
+#: src/utils/pactl.c:287
#, c-format
msgid ""
"Sink #%u\n"
@@ -2289,27 +2415,27 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:325 ../src/utils/pactl.c:431 ../src/utils/pactl.c:592
+#: src/utils/pactl.c:331 src/utils/pactl.c:437 src/utils/pactl.c:598
#, c-format
msgid "\tPorts:\n"
msgstr "\t連接埠:\n"
-#: ../src/utils/pactl.c:332 ../src/utils/pactl.c:438
+#: src/utils/pactl.c:338 src/utils/pactl.c:444
#, c-format
msgid "\tActive Port: %s\n"
msgstr "\t使用中連接埠:%s\n"
-#: ../src/utils/pactl.c:338 ../src/utils/pactl.c:444
+#: src/utils/pactl.c:344 src/utils/pactl.c:450
#, c-format
msgid "\tFormats:\n"
msgstr "\t格式:\n"
-#: ../src/utils/pactl.c:362 ../src/utils/pactl.c:920 ../src/utils/pactl.c:993
+#: src/utils/pactl.c:368 src/utils/pactl.c:928 src/utils/pactl.c:1001
#, c-format
msgid "Failed to get source information: %s"
msgstr "未能取得來源資訊:%s"
-#: ../src/utils/pactl.c:388
+#: src/utils/pactl.c:394
#, c-format
msgid ""
"Source #%u\n"
@@ -2348,20 +2474,20 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:416 ../src/utils/pactl.c:486 ../src/utils/pactl.c:529
-#: ../src/utils/pactl.c:571 ../src/utils/pactl.c:669 ../src/utils/pactl.c:670
-#: ../src/utils/pactl.c:681 ../src/utils/pactl.c:739 ../src/utils/pactl.c:740
-#: ../src/utils/pactl.c:751 ../src/utils/pactl.c:802 ../src/utils/pactl.c:803
-#: ../src/utils/pactl.c:809
+#: src/utils/pactl.c:422 src/utils/pactl.c:492 src/utils/pactl.c:535
+#: src/utils/pactl.c:577 src/utils/pactl.c:675 src/utils/pactl.c:676
+#: src/utils/pactl.c:687 src/utils/pactl.c:745 src/utils/pactl.c:746
+#: src/utils/pactl.c:757 src/utils/pactl.c:808 src/utils/pactl.c:809
+#: src/utils/pactl.c:815
msgid "n/a"
msgstr "n/a"
-#: ../src/utils/pactl.c:455 ../src/utils/pactl.c:859
+#: src/utils/pactl.c:461 src/utils/pactl.c:865
#, c-format
msgid "Failed to get module information: %s"
msgstr "未能取得模組資訊:%s"
-#: ../src/utils/pactl.c:478
+#: src/utils/pactl.c:484
#, c-format
msgid ""
"Module #%u\n"
@@ -2378,12 +2504,12 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:497
+#: src/utils/pactl.c:503
#, c-format
msgid "Failed to get client information: %s"
msgstr "未能取得客戶端資訊:%s"
-#: ../src/utils/pactl.c:523
+#: src/utils/pactl.c:529
#, c-format
msgid ""
"Client #%u\n"
@@ -2398,12 +2524,12 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:540
+#: src/utils/pactl.c:546
#, c-format
msgid "Failed to get card information: %s"
msgstr "未能取得音效卡資訊:%s"
-#: ../src/utils/pactl.c:563
+#: src/utils/pactl.c:569
#, c-format
msgid ""
"Card #%u\n"
@@ -2420,22 +2546,22 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:579
+#: src/utils/pactl.c:585
#, c-format
msgid "\tProfiles:\n"
msgstr "\t個人設定檔:\n"
-#: ../src/utils/pactl.c:581
+#: src/utils/pactl.c:587
#, c-format
msgid "\t\t%s: %s (sinks: %u, sources: %u, priority: %u, available: %s)\n"
msgstr "\t\t%s: %s (sink:%u,來源:%u,優先序:%u,可用:%s)\n"
-#: ../src/utils/pactl.c:586
+#: src/utils/pactl.c:592
#, c-format
msgid "\tActive Profile: %s\n"
msgstr "\t啟用的個人設定檔:%s\n"
-#: ../src/utils/pactl.c:600
+#: src/utils/pactl.c:606
#, c-format
msgid ""
"\t\t\tProperties:\n"
@@ -2444,17 +2570,17 @@ msgstr ""
"\t\t\t屬性:\n"
"\t\t\t\t%s\n"
-#: ../src/utils/pactl.c:605
+#: src/utils/pactl.c:611
#, c-format
msgid "\t\t\tPart of profile(s): %s"
msgstr "\t\t\t個人設定檔之部分:%s"
-#: ../src/utils/pactl.c:622 ../src/utils/pactl.c:940 ../src/utils/pactl.c:1008
+#: src/utils/pactl.c:628 src/utils/pactl.c:948 src/utils/pactl.c:1016
#, c-format
msgid "Failed to get sink input information: %s"
msgstr "未能取得 sink 輸入資訊:%s"
-#: ../src/utils/pactl.c:651
+#: src/utils/pactl.c:657
#, c-format
msgid ""
"Sink Input #%u\n"
@@ -2493,12 +2619,12 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:692 ../src/utils/pactl.c:960 ../src/utils/pactl.c:1023
+#: src/utils/pactl.c:698 src/utils/pactl.c:968 src/utils/pactl.c:1031
#, c-format
msgid "Failed to get source output information: %s"
msgstr "未能取得來源輸出資訊:%s"
-#: ../src/utils/pactl.c:721
+#: src/utils/pactl.c:727
#, c-format
msgid ""
"Source Output #%u\n"
@@ -2537,12 +2663,12 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:762
+#: src/utils/pactl.c:768
#, c-format
msgid "Failed to get sample information: %s"
msgstr "未能取得取樣資訊:%s"
-#: ../src/utils/pactl.c:789
+#: src/utils/pactl.c:795
#, c-format
msgid ""
"Sample #%u\n"
@@ -2571,161 +2697,158 @@ msgstr ""
"\t屬性:\n"
"\t\t%s\n"
-#: ../src/utils/pactl.c:817 ../src/utils/pactl.c:827
+#: src/utils/pactl.c:823 src/utils/pactl.c:833
#, c-format
msgid "Failure: %s"
msgstr "失敗:%s"
-#: ../src/utils/pactl.c:866
+#: src/utils/pactl.c:872
#, c-format
msgid "Failed to unload module: Module %s not loaded"
msgstr "無法取消模組載入:%s 模組無法載入"
-#: ../src/utils/pactl.c:884
+#: src/utils/pactl.c:890
#, c-format
+#| msgid ""
+#| "Failed to set volume: You tried to set volumes for %d channels, whereas "
+#| "channel/s supported = %d\n"
msgid ""
+"Failed to set volume: You tried to set volumes for %d channel, whereas "
+"channel(s) supported = %d\n"
+msgid_plural ""
"Failed to set volume: You tried to set volumes for %d channels, whereas "
-"channel/s supported = %d\n"
-msgstr "無法設定音量:您試圖設定 %d 個聲道的音量,而支援的聲道數為 = %d\n"
+"channel(s) supported = %d\n"
+msgstr[0] "無法設定音量:您試圖設定 %d 個聲道的音量,而支援的聲道數為 = %d\n"
-#: ../src/utils/pactl.c:1050
-#, c-format
-msgid "Failed to set format: invalid format string %s"
-msgstr "未能設定格式:無效的格式字串 %s"
-
-#: ../src/utils/pactl.c:1093
+#: src/utils/pactl.c:1101
#, c-format
msgid "Failed to upload sample: %s"
msgstr "未能上傳樣本:%s"
-#: ../src/utils/pactl.c:1110
+#: src/utils/pactl.c:1118
msgid "Premature end of file"
msgstr "未完成的檔案結尾"
-#: ../src/utils/pactl.c:1130
+#: src/utils/pactl.c:1138
msgid "new"
msgstr "新增"
-#: ../src/utils/pactl.c:1133
+#: src/utils/pactl.c:1141
msgid "change"
msgstr "變更"
-#: ../src/utils/pactl.c:1136
+#: src/utils/pactl.c:1144
msgid "remove"
msgstr "移除"
-#: ../src/utils/pactl.c:1139 ../src/utils/pactl.c:1174
+#: src/utils/pactl.c:1147 src/utils/pactl.c:1182
msgid "unknown"
msgstr "未知"
-#: ../src/utils/pactl.c:1147
+#: src/utils/pactl.c:1155
msgid "sink"
msgstr "sink"
-#: ../src/utils/pactl.c:1150
+#: src/utils/pactl.c:1158
msgid "source"
msgstr "source"
-#: ../src/utils/pactl.c:1153
+#: src/utils/pactl.c:1161
msgid "sink-input"
msgstr "sink-input"
-#: ../src/utils/pactl.c:1156
+#: src/utils/pactl.c:1164
msgid "source-output"
msgstr "source-output"
-#: ../src/utils/pactl.c:1159
+#: src/utils/pactl.c:1167
msgid "module"
msgstr "module"
-#: ../src/utils/pactl.c:1162
+#: src/utils/pactl.c:1170
msgid "client"
msgstr "client"
-#: ../src/utils/pactl.c:1165
+#: src/utils/pactl.c:1173
msgid "sample-cache"
msgstr "sample-cache"
-#: ../src/utils/pactl.c:1168
+#: src/utils/pactl.c:1176
msgid "server"
msgstr "server"
-#: ../src/utils/pactl.c:1171
+#: src/utils/pactl.c:1179
msgid "card"
msgstr "card"
-#: ../src/utils/pactl.c:1180
+#: src/utils/pactl.c:1188
#, c-format
msgid "Event '%s' on %s #%u\n"
msgstr "事件「%s」 於 %s #%u\n"
-#: ../src/utils/pactl.c:1452
+#: src/utils/pactl.c:1460
msgid "Got SIGINT, exiting."
msgstr "已取得 SIGINT,正在退出。"
-#: ../src/utils/pactl.c:1485
+#: src/utils/pactl.c:1493
msgid "Invalid volume specification"
msgstr "無效的音量規格"
-#: ../src/utils/pactl.c:1508
+#: src/utils/pactl.c:1516
msgid "Volume outside permissible range.\n"
msgstr "音量外部可允許範圍。\n"
-#: ../src/utils/pactl.c:1521
+#: src/utils/pactl.c:1529
msgid "Invalid number of volume specifications.\n"
msgstr "無效的音量規格。\n"
-#: ../src/utils/pactl.c:1533
+#: src/utils/pactl.c:1541
msgid "Inconsistent volume specification.\n"
msgstr "不一致的音量規格。\n"
-#: ../src/utils/pactl.c:1563 ../src/utils/pactl.c:1564
-#: ../src/utils/pactl.c:1565 ../src/utils/pactl.c:1566
-#: ../src/utils/pactl.c:1567 ../src/utils/pactl.c:1568
-#: ../src/utils/pactl.c:1569 ../src/utils/pactl.c:1570
-#: ../src/utils/pactl.c:1571 ../src/utils/pactl.c:1572
-#: ../src/utils/pactl.c:1573 ../src/utils/pactl.c:1574
-#: ../src/utils/pactl.c:1575 ../src/utils/pactl.c:1576
-#: ../src/utils/pactl.c:1577 ../src/utils/pactl.c:1578
-#: ../src/utils/pactl.c:1579 ../src/utils/pactl.c:1580
-#: ../src/utils/pactl.c:1581 ../src/utils/pactl.c:1582
-#: ../src/utils/pactl.c:1583
+#: src/utils/pactl.c:1571 src/utils/pactl.c:1572 src/utils/pactl.c:1573
+#: src/utils/pactl.c:1574 src/utils/pactl.c:1575 src/utils/pactl.c:1576
+#: src/utils/pactl.c:1577 src/utils/pactl.c:1578 src/utils/pactl.c:1579
+#: src/utils/pactl.c:1580 src/utils/pactl.c:1581 src/utils/pactl.c:1582
+#: src/utils/pactl.c:1583 src/utils/pactl.c:1584 src/utils/pactl.c:1585
+#: src/utils/pactl.c:1586 src/utils/pactl.c:1587 src/utils/pactl.c:1588
+#: src/utils/pactl.c:1589 src/utils/pactl.c:1590 src/utils/pactl.c:1591
msgid "[options]"
msgstr "[選項]"
-#: ../src/utils/pactl.c:1565
+#: src/utils/pactl.c:1573
msgid "[TYPE]"
msgstr "[TYPE]"
-#: ../src/utils/pactl.c:1567
+#: src/utils/pactl.c:1575
msgid "FILENAME [NAME]"
msgstr "FILENAME [NAME]"
-#: ../src/utils/pactl.c:1568
+#: src/utils/pactl.c:1576
msgid "NAME [SINK]"
msgstr "NAME [SINK]"
-#: ../src/utils/pactl.c:1577
+#: src/utils/pactl.c:1585
msgid "NAME|#N VOLUME [VOLUME ...]"
msgstr "NAME|#N VOLUME [VOLUME ...]"
-#: ../src/utils/pactl.c:1578
+#: src/utils/pactl.c:1586
msgid "#N VOLUME [VOLUME ...]"
msgstr "#N VOLUME [VOLUME ...]"
-#: ../src/utils/pactl.c:1579
+#: src/utils/pactl.c:1587
msgid "NAME|#N 1|0|toggle"
msgstr "NAME|#N 1|0|toggle"
-#: ../src/utils/pactl.c:1580
+#: src/utils/pactl.c:1588
msgid "#N 1|0|toggle"
msgstr "#N 1|0|toggle"
-#: ../src/utils/pactl.c:1581
+#: src/utils/pactl.c:1589
msgid "#N FORMATS"
msgstr "#N FORMATS"
-#: ../src/utils/pactl.c:1584
+#: src/utils/pactl.c:1592
#, c-format
msgid ""
"\n"
@@ -2736,7 +2859,7 @@ msgstr ""
"特殊名稱 @DEFAULT_SINK@、@DEFAULT_SOURCE@ 和 @DEFAULT_MONITOR@\n"
"可用來指定預設 sink、source 和 monitor。\n"
-#: ../src/utils/pactl.c:1587
+#: src/utils/pactl.c:1595
#, c-format
msgid ""
"\n"
@@ -2755,7 +2878,7 @@ msgstr ""
" -s, --server=SERVER 要連接的伺服器名稱\n"
" -n, --client-name=NAME 如何稱呼伺服器上的這個客戶端\n"
-#: ../src/utils/pactl.c:1628
+#: src/utils/pactl.c:1636
#, c-format
msgid ""
"pactl %s\n"
@@ -2766,202 +2889,212 @@ msgstr ""
"以 libpulse %s 編譯\n"
"以 libpulse %s 連結\n"
-#: ../src/utils/pactl.c:1684
+#: src/utils/pactl.c:1692
#, c-format
msgid "Specify nothing, or one of: %s"
msgstr "沒有指定,或者為右述之一:%s"
-#: ../src/utils/pactl.c:1694
+#: src/utils/pactl.c:1702
msgid "Please specify a sample file to load"
msgstr "請指定要載入的取樣檔"
-#: ../src/utils/pactl.c:1707
+#: src/utils/pactl.c:1715
msgid "Failed to open sound file."
msgstr "未能開啟音效檔。"
-#: ../src/utils/pactl.c:1719
+#: src/utils/pactl.c:1727
msgid "Warning: Failed to determine sample specification from file."
msgstr "警告:未能從檔案得知取樣規格。"
-#: ../src/utils/pactl.c:1729
+#: src/utils/pactl.c:1737
msgid "You have to specify a sample name to play"
msgstr "您必須指定一個要播放的樣本名稱"
-#: ../src/utils/pactl.c:1741
+#: src/utils/pactl.c:1749
msgid "You have to specify a sample name to remove"
msgstr "您必須指定一個要移除的樣本名稱"
-#: ../src/utils/pactl.c:1750
+#: src/utils/pactl.c:1758
msgid "You have to specify a sink input index and a sink"
msgstr "您必須指定一項 sink 輸入索引與一個 sink"
-#: ../src/utils/pactl.c:1760
+#: src/utils/pactl.c:1768
msgid "You have to specify a source output index and a source"
msgstr "您必須指定一項來源輸出索引與一個來源"
-#: ../src/utils/pactl.c:1775
+#: src/utils/pactl.c:1783
msgid "You have to specify a module name and arguments."
msgstr "您必須指定一個模組名稱與一些參數。"
-#: ../src/utils/pactl.c:1795
+#: src/utils/pactl.c:1803
msgid "You have to specify a module index or name"
msgstr "您必須指定一個模組索引或名稱"
-#: ../src/utils/pactl.c:1808
+#: src/utils/pactl.c:1816
msgid ""
"You may not specify more than one sink. You have to specify a boolean value."
msgstr "您指定的 sink 數不能超過一個。您必須指定一項布林值。"
-#: ../src/utils/pactl.c:1813 ../src/utils/pactl.c:1833
+#: src/utils/pactl.c:1821 src/utils/pactl.c:1841
msgid "Invalid suspend specification."
msgstr "無效的暫停規格。"
-#: ../src/utils/pactl.c:1828
+#: src/utils/pactl.c:1836
msgid ""
"You may not specify more than one source. You have to specify a boolean "
"value."
msgstr "您指定的來源數不能超過一個。您必須指定一項布林值。"
-#: ../src/utils/pactl.c:1845
+#: src/utils/pactl.c:1853
msgid "You have to specify a card name/index and a profile name"
msgstr "您必須指定一個音效卡名稱/索引,以及設定組合名稱"
-#: ../src/utils/pactl.c:1856
+#: src/utils/pactl.c:1864
msgid "You have to specify a sink name/index and a port name"
msgstr "您必須指定一個 sink 名稱/索引,以及連接埠名稱"
-#: ../src/utils/pactl.c:1867
+#: src/utils/pactl.c:1875
msgid "You have to specify a sink name"
msgstr "您必須指定 sink 名稱"
-#: ../src/utils/pactl.c:1877
+#: src/utils/pactl.c:1885
msgid "You have to specify a source name/index and a port name"
msgstr "您必須指定一個來源名稱/索引,以及連接埠名稱"
-#: ../src/utils/pactl.c:1888
+#: src/utils/pactl.c:1896
msgid "You have to specify a source name"
msgstr "您必須指定 source 名稱"
-#: ../src/utils/pactl.c:1898
+#: src/utils/pactl.c:1906
msgid "You have to specify a sink name/index and a volume"
msgstr "您必須指定一個 sink 名稱/索引,以及一項音量"
-#: ../src/utils/pactl.c:1911
+#: src/utils/pactl.c:1919
msgid "You have to specify a source name/index and a volume"
msgstr "您必須指定一個來源名稱/索引,以及一項音量"
-#: ../src/utils/pactl.c:1924
+#: src/utils/pactl.c:1932
msgid "You have to specify a sink input index and a volume"
msgstr "您必須指定一個 sink 輸入索引,以及一項音量"
-#: ../src/utils/pactl.c:1929
+#: src/utils/pactl.c:1937
msgid "Invalid sink input index"
msgstr "無效的 sink 輸入索引"
-#: ../src/utils/pactl.c:1940
+#: src/utils/pactl.c:1948
msgid "You have to specify a source output index and a volume"
msgstr "您必須指定一個來源輸出索引,以及一項音量"
-#: ../src/utils/pactl.c:1945
+#: src/utils/pactl.c:1953
msgid "Invalid source output index"
msgstr "無效的來源輸出索引"
-#: ../src/utils/pactl.c:1956
+#: src/utils/pactl.c:1964
msgid ""
"You have to specify a sink name/index and a mute action (0, 1, or 'toggle')"
msgstr "您必須指定 sink 名稱/索引與靜音動作(0, 1, 或「toggle」)"
-#: ../src/utils/pactl.c:1961 ../src/utils/pactl.c:1976
-#: ../src/utils/pactl.c:1996 ../src/utils/pactl.c:2014
+#: src/utils/pactl.c:1969 src/utils/pactl.c:1984 src/utils/pactl.c:2004
+#: src/utils/pactl.c:2022
msgid "Invalid mute specification"
msgstr "無效的靜音規格"
-#: ../src/utils/pactl.c:1971
+#: src/utils/pactl.c:1979
msgid ""
"You have to specify a source name/index and a mute action (0, 1, or 'toggle')"
msgstr "您必須指定來源名稱/索引與靜音動作(0, 1, 或「toggle」)"
-#: ../src/utils/pactl.c:1986
+#: src/utils/pactl.c:1994
msgid ""
"You have to specify a sink input index and a mute action (0, 1, or 'toggle')"
msgstr "您必須指定 sink 輸入索引與靜音動作(0, 1, 或「toggle」)"
-#: ../src/utils/pactl.c:1991
+#: src/utils/pactl.c:1999
msgid "Invalid sink input index specification"
msgstr "無效的 sink 輸入索引規格"
-#: ../src/utils/pactl.c:2004
+#: src/utils/pactl.c:2012
msgid ""
"You have to specify a source output index and a mute action (0, 1, or "
"'toggle')"
msgstr "您必須指定來源輸出索引與靜音動作(0, 1, 或「toggle」)"
-#: ../src/utils/pactl.c:2009
+#: src/utils/pactl.c:2017
msgid "Invalid source output index specification"
msgstr "無效的來源輸出索引規格"
-#: ../src/utils/pactl.c:2026
+#: src/utils/pactl.c:2034
msgid ""
"You have to specify a sink index and a semicolon-separated list of supported "
"formats"
msgstr "您必須指定一個 sink 索引,以及一份以半形分號分隔、列有支援格式的清單"
-#: ../src/utils/pactl.c:2038
+#: src/utils/pactl.c:2046
msgid "You have to specify a card name/index, a port name and a latency offset"
msgstr "您必須指定音效卡名稱/索引、連接埠名稱和延遲偏移"
-#: ../src/utils/pactl.c:2045
+#: src/utils/pactl.c:2053
msgid "Could not parse latency offset"
msgstr "無法解析延遲偏移"
-#: ../src/utils/pactl.c:2057
+#: src/utils/pactl.c:2065
msgid "No valid command specified."
msgstr "沒有指定有效的命令。"
-#: ../src/utils/pasuspender.c:79
+#: src/utils/pasuspender.c:79
#, c-format
msgid "fork(): %s\n"
msgstr "fork():%s\n"
-#: ../src/utils/pasuspender.c:92
+#: src/utils/pasuspender.c:92
#, c-format
msgid "execvp(): %s\n"
msgstr "execvp():%s\n"
-#: ../src/utils/pasuspender.c:111
+#: src/utils/pasuspender.c:111
#, c-format
msgid "Failure to resume: %s\n"
msgstr "未能恢復:%s\n"
-#: ../src/utils/pasuspender.c:145
+#: src/utils/pasuspender.c:145
#, c-format
msgid "Failure to suspend: %s\n"
msgstr "未能暫停:%s\n"
-#: ../src/utils/pasuspender.c:170
+#: src/utils/pasuspender.c:170
#, c-format
msgid "WARNING: Sound server is not local, not suspending.\n"
msgstr "警告:音效伺服器並非本機,不會暫停。\n"
-#: ../src/utils/pasuspender.c:183
+#: src/utils/pasuspender.c:183
#, c-format
msgid "Connection failure: %s\n"
msgstr "連線失敗:%s\n"
-#: ../src/utils/pasuspender.c:201
+#: src/utils/pasuspender.c:201
#, c-format
msgid "Got SIGINT, exiting.\n"
msgstr "已取得 SIGINT,正在退出。\n"
-#: ../src/utils/pasuspender.c:219
+#: src/utils/pasuspender.c:219
#, c-format
msgid "WARNING: Child process terminated by signal %u\n"
msgstr "警告:子代程序已被訊號 %u 所終止\n"
-#: ../src/utils/pasuspender.c:228
+#: src/utils/pasuspender.c:228
#, 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"
msgid ""
-"%s [options] ... \n"
+"%s [options] -- PROGRAM [ARGUMENTS ...]\n"
+"\n"
+"Temporarily suspend PulseAudio while PROGRAM runs.\n"
"\n"
" -h, --help Show this help\n"
" --version Show version\n"
@@ -2969,14 +3102,16 @@ msgid ""
"to\n"
"\n"
msgstr ""
-"%s [選項] ... \n"
+"%s [選項] -- 程式 [參數 ...]\n"
"\n"
-" -h, --help 顯示此幫助\n"
+"<程式> 執行時,暫時暫停 PulseAudio。"
+"\n"
+" -h, --help 顯示此說明\n"
" --version 顯示版本\n"
-" -s, --server=SERVER 要連接的伺服器名稱\n"
+" -s, --server=SERVER 要連線的伺服器名稱\n"
"\n"
-#: ../src/utils/pasuspender.c:266
+#: src/utils/pasuspender.c:267
#, c-format
msgid ""
"pasuspender %s\n"
@@ -2987,22 +3122,22 @@ msgstr ""
"以 libpulse %s 編譯\n"
"以 libpulse %s 連結\n"
-#: ../src/utils/pasuspender.c:295
+#: src/utils/pasuspender.c:296
#, c-format
msgid "pa_mainloop_new() failed.\n"
msgstr "pa_mainloop_new() 失敗。\n"
-#: ../src/utils/pasuspender.c:308
+#: src/utils/pasuspender.c:309
#, c-format
msgid "pa_context_new() failed.\n"
msgstr "pa_context_new() 失敗。\n"
-#: ../src/utils/pasuspender.c:320
+#: src/utils/pasuspender.c:321
#, c-format
msgid "pa_mainloop_run() failed.\n"
msgstr "pa_mainloop_run() 失敗。\n"
-#: ../src/utils/pax11publish.c:58
+#: src/utils/pax11publish.c:58
#, c-format
msgid ""
"%s [-D display] [-S server] [-O sink] [-I source] [-c file] [-d|-e|-i|-r]\n"
@@ -3020,56 +3155,87 @@ msgstr ""
" -i 從 X11 顯示匯入 PulseAudio 資料至本地端環境變數與 cookie 檔案。\n"
" -r 從 X11 顯示移除 PulseAudio 資料\n"
-#: ../src/utils/pax11publish.c:91
+#: src/utils/pax11publish.c:91
#, c-format
msgid "Failed to parse command line.\n"
msgstr "未能解析命令列。\n"
-#: ../src/utils/pax11publish.c:110
+#: src/utils/pax11publish.c:110
#, c-format
msgid "Server: %s\n"
msgstr "伺服器:%s\n"
-#: ../src/utils/pax11publish.c:112
+#: src/utils/pax11publish.c:112
#, c-format
msgid "Source: %s\n"
msgstr "來源:%s\n"
-#: ../src/utils/pax11publish.c:114
+#: src/utils/pax11publish.c:114
#, c-format
msgid "Sink: %s\n"
msgstr "Sink:%s\n"
-#: ../src/utils/pax11publish.c:116
+#: src/utils/pax11publish.c:116
#, c-format
msgid "Cookie: %s\n"
msgstr "Cookie:%s\n"
-#: ../src/utils/pax11publish.c:134
+#: src/utils/pax11publish.c:134
#, c-format
msgid "Failed to parse cookie data\n"
msgstr "未能解析 cookie 資料\n"
-#: ../src/utils/pax11publish.c:139
+#: src/utils/pax11publish.c:139
#, c-format
msgid "Failed to save cookie data\n"
msgstr "未能儲存 cookie 資料\n"
-#: ../src/utils/pax11publish.c:168
+#: src/utils/pax11publish.c:168
#, c-format
msgid "Failed to get FQDN.\n"
msgstr "未能取得 FQDN。\n"
-#: ../src/utils/pax11publish.c:188
+#: src/utils/pax11publish.c:188
#, c-format
msgid "Failed to load cookie data\n"
msgstr "未能載入 cookie 資料\n"
-#: ../src/utils/pax11publish.c:206
+#: src/utils/pax11publish.c:206
#, c-format
msgid "Not yet implemented.\n"
msgstr "尚未實作。\n"
+#~ msgid "Failed to initialize daemon."
+#~ msgstr "未能初始化幕後程式。"
+
+#, c-format
+#~ msgid ""
+#~ "ALSA woke us up to write new data to the device, but there was actually "
+#~ "nothing to write!\n"
+#~ "Most likely this is a bug in the ALSA driver '%s'. Please report this "
+#~ "issue to the ALSA developers.\n"
+#~ "We were woken up with POLLOUT set -- however a subsequent snd_pcm_avail() "
+#~ "returned 0 or another value < min_avail."
+#~ msgstr ""
+#~ "ALSA 喚醒我們以寫入新資料至該裝置,但實際上沒有要寫入的資料!\n"
+#~ "這很可能是 ALSA 驅動程式「%s」的臭蟲。請回報此問題給 ALSA 開發者。\n"
+#~ "我們被 POLLOUT 設定喚醒 -- 然而後續的 snd_pcm_avail() 傳回 0 或另一個值 < "
+#~ "min_avail。"
+
+#, c-format
+#~ msgid ""
+#~ "ALSA woke us up to read new data from the device, but there was actually "
+#~ "nothing to read!\n"
+#~ "Most likely this is a bug in the ALSA driver '%s'. Please report this "
+#~ "issue to the ALSA developers.\n"
+#~ "We were woken up with POLLIN set -- however a subsequent snd_pcm_avail() "
+#~ "returned 0 or another value < min_avail."
+#~ msgstr ""
+#~ "ALSA 喚醒我們從該裝置讀取新資料,但實際上沒有可讀取的資料!\n"
+#~ "這很可能是 ALSA 驅動程式「%s」的臭蟲。請回報此問題給 ALSA 開發者。\n"
+#~ "我們被 POLLIN 設定喚醒 -- 然而後續的 snd_pcm_avail() 傳回 0 或另一個值 < "
+#~ "min_avail。"
+
#~ msgid ""
#~ "sink_name=<name for the sink> sink_properties=<properties for the sink> "
#~ "master=<name of sink to filter> format=<sample format> rate=<sample rate> "
diff --git a/scripts/Dockerfile b/scripts/Dockerfile
deleted file mode 100644
index e75dbbd..0000000
--- a/scripts/Dockerfile
+++ /dev/null
@@ -1,65 +0,0 @@
-# Start with current Ubuntu LTS
-FROM ubuntu:18.04
-
-# Add a PulseAudio's dependencies
-RUN apt-get update && apt-get install -y \
- autoconf \
- automake \
- autopoint \
- bash-completion \
- check \
- dbus-x11 \
- g++ \
- gcc \
- gettext \
- git-core \
- libasound2-dev \
- libasyncns-dev \
- libavahi-client-dev \
- libbluetooth-dev \
- libcap-dev \
- libfftw3-dev \
- libglib2.0-dev \
- libgtk-3-dev \
- libice-dev \
- libjack-dev \
- liblircclient-dev \
- libltdl-dev \
- liborc-0.4-dev \
- libsbc-dev \
- libsndfile1-dev \
- libsoxr-dev \
- libspeexdsp-dev \
- libssl-dev \
- libsystemd-dev \
- libtdb-dev \
- libudev-dev \
- libwebrtc-audio-processing-dev \
- libwrap0-dev \
- libx11-xcb-dev \
- libxcb1-dev \
- libxml-parser-perl \
- libxml2-utils \
- libxtst-dev \
- make \
- ninja-build \
- python3-setuptools \
- systemd
-
-# Install meson from upstream tarball
-ARG MESON_VERSION=0.50.0
-RUN apt-get install -y wget && \
- wget -q https://github.com/mesonbuild/meson/releases/download/${MESON_VERSION}/meson-${MESON_VERSION}.tar.gz && \
- tar -xf meson-${MESON_VERSION}.tar.gz && \
- cd meson-${MESON_VERSION} && \
- python3 setup.py install
-
-# Add a user and set as default for the build. This is safer, in general, and
-# allows us to avoid having to explicitly allow running as root in the
-# check-daemon stage.
-RUN groupadd -g 1000 a_group && \
- useradd a_user -u 1000 -g a_group -m
-USER a_user:a_group
-
-# And make sure subsequent commands are run in the user's home directory
-WORKDIR /home/a_user
diff --git a/shell-completion/bash/meson.build b/shell-completion/bash/meson.build
index b5b00f1..db4b00b 100644
--- a/shell-completion/bash/meson.build
+++ b/shell-completion/bash/meson.build
@@ -1,18 +1,20 @@
-aliases = [
- 'pacat',
- 'pacmd',
- 'pactl',
- 'padsp',
- 'paplay',
- 'parec',
- 'parecord',
- 'pasuspender',
-]
+if bashcompletiondir != 'no'
+ aliases = [
+ 'pacat',
+ 'pacmd',
+ 'pactl',
+ 'padsp',
+ 'paplay',
+ 'parec',
+ 'parecord',
+ 'pasuspender',
+ ]
-install_data('pulseaudio', install_dir : bashcompletiondir)
+ install_data('pulseaudio', install_dir : bashcompletiondir)
-foreach alias : aliases
- dst = join_paths(bashcompletiondir, alias)
- cmd = 'ln -fs @0@ $DESTDIR@1@'.format('pulseaudio', dst)
- meson.add_install_script('sh', '-c', cmd)
-endforeach
+ foreach alias : aliases
+ dst = join_paths(bashcompletiondir, alias)
+ cmd = 'ln -fs @0@ $DESTDIR@1@'.format('pulseaudio', dst)
+ meson.add_install_script('sh', '-c', cmd)
+ endforeach
+endif
diff --git a/shell-completion/bash/pulseaudio b/shell-completion/bash/pulseaudio
index e473b9c..08f247e 100644
--- a/shell-completion/bash/pulseaudio
+++ b/shell-completion/bash/pulseaudio
@@ -37,7 +37,7 @@ __source_outputs () {
}
__ports () {
- pactl list cards 2> /dev/null | awk -e \
+ pactl list cards 2> /dev/null | awk -- \
'/^\tPorts:/ {
flag=1; next
}
@@ -57,7 +57,7 @@ __ports () {
}
__profiles () {
- pactl list cards 2> /dev/null | awk -e \
+ pactl list cards 2> /dev/null | awk -- \
'/^\tProfiles:/ {
flag=1; next
}
@@ -116,11 +116,12 @@ _pactl() {
modules samples clients'
local commands=(stat info list exit upload-sample play-sample remove-sample
load-module unload-module move-sink-input move-source-output
- suspend-sink suspend-source set-card-profile set-sink-port
- set-source-port set-sink-volume set-source-volume
- set-sink-input-volume set-source-output-volume set-sink-mute
- set-source-mute set-sink-input-mute set-source-output-mute
- set-sink-formats set-port-latency-offset subscribe help)
+ suspend-sink suspend-source set-card-profile set-default-sink
+ set-sink-port set-default-source set-source-port set-sink-volume
+ set-source-volume set-sink-input-volume set-source-output-volume
+ set-sink-mute set-source-mute set-sink-input-mute
+ set-source-output-mute set-sink-formats set-port-latency-offset
+ subscribe help)
_init_completion -n = || return
preprev=${words[$cword-2]}
diff --git a/shell-completion/zsh/meson.build b/shell-completion/zsh/meson.build
index 88c3355..489be56 100644
--- a/shell-completion/zsh/meson.build
+++ b/shell-completion/zsh/meson.build
@@ -1 +1,3 @@
-install_data('_pulseaudio', install_dir : zshcompletiondir)
+if zshcompletiondir != 'no'
+ install_data('_pulseaudio', install_dir : zshcompletiondir)
+endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 437311d..0f1ded7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1176,13 +1176,21 @@ libprotocol_esound_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libp
endif
librtp_la_SOURCES = \
- modules/rtp/rtp.c modules/rtp/rtp.h \
+ modules/rtp/rtp-common.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_CFLAGS = $(AM_CFLAGS)
librtp_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
librtp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+if HAVE_GSTREAMER
+librtp_la_SOURCES += modules/rtp/rtp-gstreamer.c
+librtp_la_CFLAGS += $(GSTREAMER_CFLAGS)
+librtp_la_LIBADD += $(GSTREAMER_LIBS)
+else
+librtp_la_SOURCES += modules/rtp/rtp-native.c
+endif
libraop_la_SOURCES = \
modules/raop/raop-util.c modules/raop/raop-util.h \
@@ -1345,8 +1353,8 @@ dist_alsaprofilesets_DATA = \
modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf \
modules/alsa/mixer/profile-sets/kinect-audio.conf \
modules/alsa/mixer/profile-sets/sb-omni-surround-5.1.conf \
- modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf \
- modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf \
+ modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf \
+ modules/alsa/mixer/profile-sets/usb-gaming-headset.conf \
modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \
modules/alsa/mixer/profile-sets/cmedia-high-speed-true-hdaudio.conf
@@ -1391,11 +1399,11 @@ dist_alsapaths_DATA = \
modules/alsa/mixer/paths/hdmi-output-5.conf \
modules/alsa/mixer/paths/hdmi-output-6.conf \
modules/alsa/mixer/paths/hdmi-output-7.conf \
- modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf \
- modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf \
- modules/alsa/mixer/paths/steelseries-arctis-7-input.conf \
- modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf \
- modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf
+ modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf \
+ modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf \
+ modules/alsa/mixer/paths/usb-gaming-headset-input.conf \
+ modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf \
+ modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf
endif
@@ -1734,9 +1742,9 @@ module_tunnel_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
module_tunnel_sink_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
module_tunnel_source_la_SOURCES = modules/module-tunnel.c
-module_tunnel_source_la_LDFLAGS = $(MODULE_LDFLAGS) $(X11_CFLAGS)
+module_tunnel_source_la_LDFLAGS = $(MODULE_LDFLAGS)
module_tunnel_source_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
-module_tunnel_source_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_tunnel_source
+module_tunnel_source_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS) -DPA_MODULE_NAME=module_tunnel_source
module_loopback_la_SOURCES = modules/module-loopback.c
module_loopback_la_LDFLAGS = $(MODULE_LDFLAGS)
@@ -2049,12 +2057,12 @@ endif
module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c
module_rtp_send_la_LDFLAGS = $(MODULE_LDFLAGS)
module_rtp_send_la_LIBADD = $(MODULE_LIBADD) librtp.la
-module_rtp_send_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_rtp_send
+module_rtp_send_la_CFLAGS = $(AM_CFLAGS) $(GSTREAMER_CFLAGS) -DPA_MODULE_NAME=module_rtp_send
module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c
module_rtp_recv_la_LDFLAGS = $(MODULE_LDFLAGS)
module_rtp_recv_la_LIBADD = $(MODULE_LIBADD) librtp.la
-module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_rtp_recv
+module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) $(GSTREAMER_CFLAGS) -DPA_MODULE_NAME=module_rtp_recv
# JACK
diff --git a/src/Makefile.in b/src/Makefile.in
index ab5ac17..5b7d99d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -288,122 +288,126 @@ bin_PROGRAMS = pulseaudio$(EXEEXT) pacat$(EXEEXT) pactl$(EXEEXT) \
@HAVE_DBUS_TRUE@am__append_82 = $(DBUS_CFLAGS)
@HAVE_DBUS_TRUE@am__append_83 = $(DBUS_LIBS)
+@HAVE_GSTREAMER_TRUE@am__append_84 = modules/rtp/rtp-gstreamer.c
+@HAVE_GSTREAMER_TRUE@am__append_85 = $(GSTREAMER_CFLAGS)
+@HAVE_GSTREAMER_TRUE@am__append_86 = $(GSTREAMER_LIBS)
+@HAVE_GSTREAMER_FALSE@am__append_87 = modules/rtp/rtp-native.c
###################################
# Plug-in libraries #
###################################
# Serveral module (e.g. libalsa-util.la)
-@HAVE_DBUS_TRUE@am__append_84 = \
+@HAVE_DBUS_TRUE@am__append_88 = \
@HAVE_DBUS_TRUE@ module-console-kit.la
-@HAVE_ESOUND_TRUE@am__append_85 = \
+@HAVE_ESOUND_TRUE@am__append_89 = \
@HAVE_ESOUND_TRUE@ module-esound-protocol-tcp.la \
@HAVE_ESOUND_TRUE@ module-esound-sink.la
# See comment at librtp.la above
-@OS_IS_WIN32_FALSE@am__append_86 = \
+@OS_IS_WIN32_FALSE@am__append_90 = \
@OS_IS_WIN32_FALSE@ module-rtp-send.la \
@OS_IS_WIN32_FALSE@ module-rtp-recv.la
-@HAVE_AF_UNIX_TRUE@am__append_87 = \
+@HAVE_AF_UNIX_TRUE@am__append_91 = \
@HAVE_AF_UNIX_TRUE@ module-cli-protocol-unix.la \
@HAVE_AF_UNIX_TRUE@ module-simple-protocol-unix.la \
@HAVE_AF_UNIX_TRUE@ module-http-protocol-unix.la \
@HAVE_AF_UNIX_TRUE@ module-native-protocol-unix.la
-@HAVE_AF_UNIX_TRUE@@HAVE_ESOUND_TRUE@am__append_88 = \
+@HAVE_AF_UNIX_TRUE@@HAVE_ESOUND_TRUE@am__append_92 = \
@HAVE_AF_UNIX_TRUE@@HAVE_ESOUND_TRUE@ module-esound-protocol-unix.la
-@HAVE_MKFIFO_TRUE@am__append_89 = \
+@HAVE_MKFIFO_TRUE@am__append_93 = \
@HAVE_MKFIFO_TRUE@ module-pipe-sink.la \
@HAVE_MKFIFO_TRUE@ module-pipe-source.la
-@HAVE_ESOUND_TRUE@@OS_IS_WIN32_FALSE@am__append_90 = \
+@HAVE_ESOUND_TRUE@@OS_IS_WIN32_FALSE@am__append_94 = \
@HAVE_ESOUND_TRUE@@OS_IS_WIN32_FALSE@ module-esound-compat-spawnfd.la \
@HAVE_ESOUND_TRUE@@OS_IS_WIN32_FALSE@ module-esound-compat-spawnpid.la
-@HAVE_REGEX_TRUE@am__append_91 = \
+@HAVE_REGEX_TRUE@am__append_95 = \
@HAVE_REGEX_TRUE@ module-match.la
-@HAVE_X11_TRUE@am__append_92 = \
+@HAVE_X11_TRUE@am__append_96 = \
@HAVE_X11_TRUE@ module-x11-bell.la \
@HAVE_X11_TRUE@ module-x11-publish.la \
@HAVE_X11_TRUE@ module-x11-xsmp.la \
@HAVE_X11_TRUE@ module-x11-cork-request.la
-@HAVE_OSS_OUTPUT_TRUE@am__append_93 = \
+@HAVE_OSS_OUTPUT_TRUE@am__append_97 = \
@HAVE_OSS_OUTPUT_TRUE@ liboss-util.la \
@HAVE_OSS_OUTPUT_TRUE@ module-oss.la
-@HAVE_COREAUDIO_TRUE@am__append_94 = \
+@HAVE_COREAUDIO_TRUE@am__append_98 = \
@HAVE_COREAUDIO_TRUE@ module-coreaudio-detect.la \
@HAVE_COREAUDIO_TRUE@ module-coreaudio-device.la
pulselibexec_PROGRAMS = $(am__EXEEXT_16) $(am__EXEEXT_17)
-@HAVE_ALSA_TRUE@am__append_95 = \
+@HAVE_ALSA_TRUE@am__append_99 = \
@HAVE_ALSA_TRUE@ libalsa-util.la \
@HAVE_ALSA_TRUE@ module-alsa-sink.la \
@HAVE_ALSA_TRUE@ module-alsa-source.la \
@HAVE_ALSA_TRUE@ module-alsa-card.la
-@HAVE_SOLARIS_TRUE@am__append_96 = \
+@HAVE_SOLARIS_TRUE@am__append_100 = \
@HAVE_SOLARIS_TRUE@ module-solaris.la
-@HAVE_AVAHI_TRUE@am__append_97 = \
+@HAVE_AVAHI_TRUE@am__append_101 = \
@HAVE_AVAHI_TRUE@ module-zeroconf-publish.la \
@HAVE_AVAHI_TRUE@ module-zeroconf-discover.la
-@HAVE_BONJOUR_TRUE@am__append_98 = \
+@HAVE_BONJOUR_TRUE@am__append_102 = \
@HAVE_BONJOUR_TRUE@ module-bonjour-publish.la
-@HAVE_LIRC_TRUE@am__append_99 = \
+@HAVE_LIRC_TRUE@am__append_103 = \
@HAVE_LIRC_TRUE@ module-lirc.la
-@HAVE_EVDEV_TRUE@am__append_100 = \
+@HAVE_EVDEV_TRUE@am__append_104 = \
@HAVE_EVDEV_TRUE@ module-mmkbd-evdev.la
-@HAVE_JACK_TRUE@am__append_101 = \
+@HAVE_JACK_TRUE@am__append_105 = \
@HAVE_JACK_TRUE@ module-jack-sink.la \
@HAVE_JACK_TRUE@ module-jack-source.la
-@HAVE_DBUS_TRUE@@HAVE_JACK_TRUE@am__append_102 = \
+@HAVE_DBUS_TRUE@@HAVE_JACK_TRUE@am__append_106 = \
@HAVE_DBUS_TRUE@@HAVE_JACK_TRUE@ module-jackdbus-detect.la
-@HAVE_GCONF_TRUE@am__append_103 = \
+@HAVE_GCONF_TRUE@am__append_107 = \
@HAVE_GCONF_TRUE@ module-gconf.la
-@HAVE_GCONF_TRUE@am__append_104 = \
+@HAVE_GCONF_TRUE@am__append_108 = \
@HAVE_GCONF_TRUE@ gconf-helper
-@HAVE_GSETTINGS_TRUE@am__append_105 = \
+@HAVE_GSETTINGS_TRUE@am__append_109 = \
@HAVE_GSETTINGS_TRUE@ module-gsettings.la
-@HAVE_GSETTINGS_TRUE@am__append_106 = \
+@HAVE_GSETTINGS_TRUE@am__append_110 = \
@HAVE_GSETTINGS_TRUE@ gsettings-helper
-@HAVE_WAVEOUT_TRUE@am__append_107 = \
+@HAVE_WAVEOUT_TRUE@am__append_111 = \
@HAVE_WAVEOUT_TRUE@ module-waveout.la
-@HAVE_HAL_COMPAT_TRUE@am__append_108 = \
+@HAVE_HAL_COMPAT_TRUE@am__append_112 = \
@HAVE_HAL_COMPAT_TRUE@ module-hal-detect.la
-@HAVE_UDEV_TRUE@am__append_109 = \
+@HAVE_UDEV_TRUE@am__append_113 = \
@HAVE_UDEV_TRUE@ module-udev-detect.la
-@HAVE_SYSTEMD_LOGIN_TRUE@am__append_110 = \
+@HAVE_SYSTEMD_LOGIN_TRUE@am__append_114 = \
@HAVE_SYSTEMD_LOGIN_TRUE@ module-systemd-login.la
-@HAVE_DBUS_TRUE@am__append_111 = \
+@HAVE_DBUS_TRUE@am__append_115 = \
@HAVE_DBUS_TRUE@ module-rygel-media-server.la \
@HAVE_DBUS_TRUE@ module-dbus-protocol.la
-@HAVE_BLUEZ_TRUE@am__append_112 = \
+@HAVE_BLUEZ_TRUE@am__append_116 = \
@HAVE_BLUEZ_TRUE@ module-bluetooth-discover.la \
@HAVE_BLUEZ_TRUE@ module-bluetooth-policy.la
-@HAVE_BLUEZ_5_TRUE@am__append_113 = \
+@HAVE_BLUEZ_5_TRUE@am__append_117 = \
@HAVE_BLUEZ_5_TRUE@ libbluez5-util.la \
@HAVE_BLUEZ_5_TRUE@ module-bluez5-discover.la \
@HAVE_BLUEZ_5_TRUE@ module-bluez5-device.la
@@ -411,46 +415,46 @@ pulselibexec_PROGRAMS = $(am__EXEEXT_16) $(am__EXEEXT_17)
# RAOP depends on RTP, and we don't support RTP on Windows, see comment at
# librtp.la above.
-@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@am__append_114 = \
+@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@am__append_118 = \
@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@ libraop.la \
@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@ module-raop-sink.la
-@HAVE_AVAHI_TRUE@@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@am__append_115 = \
+@HAVE_AVAHI_TRUE@@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@am__append_119 = \
@HAVE_AVAHI_TRUE@@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@ module-raop-discover.la
-@HAVE_DBUS_TRUE@@HAVE_FFTW_TRUE@am__append_116 = \
+@HAVE_DBUS_TRUE@@HAVE_FFTW_TRUE@am__append_120 = \
@HAVE_DBUS_TRUE@@HAVE_FFTW_TRUE@ module-equalizer-sink.la
-@HAVE_DBUS_TRUE@@HAVE_FFTW_TRUE@am__append_117 = utils/qpaeq
-@HAVE_DBUS_TRUE@am__append_118 = $(DBUS_CFLAGS)
-@HAVE_DBUS_TRUE@am__append_119 = $(DBUS_LIBS)
-@HAVE_UDEV_TRUE@am__append_120 = modules/udev-util.h modules/udev-util.c
-@HAVE_UDEV_TRUE@am__append_121 = $(UDEV_LIBS)
-@HAVE_UDEV_TRUE@am__append_122 = $(UDEV_CFLAGS)
-@HAVE_DBUS_TRUE@am__append_123 = modules/reserve.h modules/reserve.c modules/reserve-monitor.h modules/reserve-monitor.c
-@HAVE_DBUS_TRUE@am__append_124 = $(DBUS_LIBS)
-@HAVE_DBUS_TRUE@am__append_125 = $(DBUS_CFLAGS)
-@HAVE_DBUS_TRUE@am__append_126 = $(DBUS_LIBS)
-@HAVE_DBUS_TRUE@am__append_127 = $(DBUS_CFLAGS)
+@HAVE_DBUS_TRUE@@HAVE_FFTW_TRUE@am__append_121 = utils/qpaeq
+@HAVE_DBUS_TRUE@am__append_122 = $(DBUS_CFLAGS)
+@HAVE_DBUS_TRUE@am__append_123 = $(DBUS_LIBS)
+@HAVE_UDEV_TRUE@am__append_124 = modules/udev-util.h modules/udev-util.c
+@HAVE_UDEV_TRUE@am__append_125 = $(UDEV_LIBS)
+@HAVE_UDEV_TRUE@am__append_126 = $(UDEV_CFLAGS)
+@HAVE_DBUS_TRUE@am__append_127 = modules/reserve.h modules/reserve.c modules/reserve-monitor.h modules/reserve-monitor.c
@HAVE_DBUS_TRUE@am__append_128 = $(DBUS_LIBS)
@HAVE_DBUS_TRUE@am__append_129 = $(DBUS_CFLAGS)
-@HAVE_ADRIAN_EC_TRUE@am__append_130 = \
+@HAVE_DBUS_TRUE@am__append_130 = $(DBUS_LIBS)
+@HAVE_DBUS_TRUE@am__append_131 = $(DBUS_CFLAGS)
+@HAVE_DBUS_TRUE@am__append_132 = $(DBUS_LIBS)
+@HAVE_DBUS_TRUE@am__append_133 = $(DBUS_CFLAGS)
+@HAVE_ADRIAN_EC_TRUE@am__append_134 = \
@HAVE_ADRIAN_EC_TRUE@ modules/echo-cancel/adrian-aec.c modules/echo-cancel/adrian-aec.h \
@HAVE_ADRIAN_EC_TRUE@ modules/echo-cancel/adrian.c modules/echo-cancel/adrian.h
-@HAVE_ADRIAN_EC_TRUE@am__append_131 = -DHAVE_ADRIAN_EC=1
-@HAVE_ADRIAN_EC_TRUE@am__append_132 = modules/echo-cancel/adrian-aec
-@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__append_133 = $(ORC_LIBS)
-@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__append_134 = $(ORC_CFLAGS) -I$(top_builddir)/src/modules/echo-cancel
-@HAVE_SPEEX_TRUE@am__append_135 = modules/echo-cancel/speex.c
-@HAVE_SPEEX_TRUE@am__append_136 = $(LIBSPEEX_CFLAGS)
-@HAVE_SPEEX_TRUE@am__append_137 = $(LIBSPEEX_LIBS)
-@HAVE_WEBRTC_TRUE@am__append_138 = -DHAVE_WEBRTC=1
-@HAVE_WEBRTC_TRUE@am__append_139 = libwebrtc-util.la
-@HAVE_BLUEZ_5_OFONO_HEADSET_TRUE@am__append_140 = \
+@HAVE_ADRIAN_EC_TRUE@am__append_135 = -DHAVE_ADRIAN_EC=1
+@HAVE_ADRIAN_EC_TRUE@am__append_136 = modules/echo-cancel/adrian-aec
+@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__append_137 = $(ORC_LIBS)
+@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__append_138 = $(ORC_CFLAGS) -I$(top_builddir)/src/modules/echo-cancel
+@HAVE_SPEEX_TRUE@am__append_139 = modules/echo-cancel/speex.c
+@HAVE_SPEEX_TRUE@am__append_140 = $(LIBSPEEX_CFLAGS)
+@HAVE_SPEEX_TRUE@am__append_141 = $(LIBSPEEX_LIBS)
+@HAVE_WEBRTC_TRUE@am__append_142 = -DHAVE_WEBRTC=1
+@HAVE_WEBRTC_TRUE@am__append_143 = libwebrtc-util.la
+@HAVE_BLUEZ_5_OFONO_HEADSET_TRUE@am__append_144 = \
@HAVE_BLUEZ_5_OFONO_HEADSET_TRUE@ modules/bluetooth/backend-ofono.c
-@HAVE_BLUEZ_5_NATIVE_HEADSET_TRUE@am__append_141 = \
+@HAVE_BLUEZ_5_NATIVE_HEADSET_TRUE@am__append_145 = \
@HAVE_BLUEZ_5_NATIVE_HEADSET_TRUE@ modules/bluetooth/backend-native.c
subdir = src
@@ -1132,16 +1136,30 @@ libraop_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(CFLAGS) $(libraop_la_LDFLAGS) $(LDFLAGS) -o $@
@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@am_libraop_la_rpath = -rpath \
@HAVE_OPENSSL_TRUE@@OS_IS_WIN32_FALSE@ $(modlibexecdir)
+@HAVE_GSTREAMER_TRUE@am__DEPENDENCIES_13 = $(am__DEPENDENCIES_1)
librtp_la_DEPENDENCIES = $(am__DEPENDENCIES_2) \
libpulsecore-@PA_MAJORMINOR@.la \
- libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
-am_librtp_la_OBJECTS = modules/rtp/rtp.lo modules/rtp/sdp.lo \
- modules/rtp/sap.lo modules/rtp/rtsp_client.lo \
- modules/rtp/headerlist.lo
+ libpulsecommon-@PA_MAJORMINOR@.la libpulse.la \
+ $(am__DEPENDENCIES_13)
+am__librtp_la_SOURCES_DIST = modules/rtp/rtp-common.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 modules/rtp/rtp-gstreamer.c \
+ modules/rtp/rtp-native.c
+@HAVE_GSTREAMER_TRUE@am__objects_23 = \
+@HAVE_GSTREAMER_TRUE@ modules/rtp/librtp_la-rtp-gstreamer.lo
+@HAVE_GSTREAMER_FALSE@am__objects_24 = \
+@HAVE_GSTREAMER_FALSE@ modules/rtp/librtp_la-rtp-native.lo
+am_librtp_la_OBJECTS = modules/rtp/librtp_la-rtp-common.lo \
+ modules/rtp/librtp_la-sdp.lo modules/rtp/librtp_la-sap.lo \
+ modules/rtp/librtp_la-rtsp_client.lo \
+ modules/rtp/librtp_la-headerlist.lo $(am__objects_23) \
+ $(am__objects_24)
librtp_la_OBJECTS = $(am_librtp_la_OBJECTS)
librtp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(librtp_la_LDFLAGS) $(LDFLAGS) -o $@
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(librtp_la_CFLAGS) \
+ $(CFLAGS) $(librtp_la_LDFLAGS) $(LDFLAGS) -o $@
@OS_IS_WIN32_FALSE@am_librtp_la_rpath = -rpath $(modlibexecdir)
@HAVE_WEBRTC_TRUE@libwebrtc_util_la_DEPENDENCIES = \
@HAVE_WEBRTC_TRUE@ libpulsecore-@PA_MAJORMINOR@.la \
@@ -1412,23 +1430,23 @@ module_device_restore_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(module_device_restore_la_CFLAGS) $(CFLAGS) \
$(module_device_restore_la_LDFLAGS) $(LDFLAGS) -o $@
-@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__DEPENDENCIES_13 = \
+@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__DEPENDENCIES_14 = \
@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@ $(am__DEPENDENCIES_1)
module_echo_cancel_la_DEPENDENCIES = $(am__DEPENDENCIES_3) \
- $(am__DEPENDENCIES_13) $(am__DEPENDENCIES_10) \
- $(am__append_139)
+ $(am__DEPENDENCIES_14) $(am__DEPENDENCIES_10) \
+ $(am__append_143)
am__module_echo_cancel_la_SOURCES_DIST = \
modules/echo-cancel/module-echo-cancel.c \
modules/echo-cancel/null.c modules/echo-cancel/echo-cancel.h \
modules/echo-cancel/adrian-aec.c \
modules/echo-cancel/adrian-aec.h modules/echo-cancel/adrian.c \
modules/echo-cancel/adrian.h modules/echo-cancel/speex.c
-@HAVE_ADRIAN_EC_TRUE@am__objects_23 = modules/echo-cancel/module_echo_cancel_la-adrian-aec.lo \
+@HAVE_ADRIAN_EC_TRUE@am__objects_25 = modules/echo-cancel/module_echo_cancel_la-adrian-aec.lo \
@HAVE_ADRIAN_EC_TRUE@ modules/echo-cancel/module_echo_cancel_la-adrian.lo
-@HAVE_SPEEX_TRUE@am__objects_24 = modules/echo-cancel/module_echo_cancel_la-speex.lo
+@HAVE_SPEEX_TRUE@am__objects_26 = modules/echo-cancel/module_echo_cancel_la-speex.lo
am_module_echo_cancel_la_OBJECTS = modules/echo-cancel/module_echo_cancel_la-module-echo-cancel.lo \
modules/echo-cancel/module_echo_cancel_la-null.lo \
- $(am__objects_23) $(am__objects_24)
+ $(am__objects_25) $(am__objects_26)
@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@nodist_module_echo_cancel_la_OBJECTS = modules/echo-cancel/module_echo_cancel_la-adrian-aec-orc-gen.lo
module_echo_cancel_la_OBJECTS = $(am_module_echo_cancel_la_OBJECTS) \
$(nodist_module_echo_cancel_la_OBJECTS)
@@ -2236,20 +2254,20 @@ am__echo_cancel_test_SOURCES_DIST = \
modules/echo-cancel/adrian-aec.c \
modules/echo-cancel/adrian-aec.h modules/echo-cancel/adrian.c \
modules/echo-cancel/adrian.h modules/echo-cancel/speex.c
-@HAVE_ADRIAN_EC_TRUE@am__objects_25 = modules/echo-cancel/echo_cancel_test-adrian-aec.$(OBJEXT) \
+@HAVE_ADRIAN_EC_TRUE@am__objects_27 = modules/echo-cancel/echo_cancel_test-adrian-aec.$(OBJEXT) \
@HAVE_ADRIAN_EC_TRUE@ modules/echo-cancel/echo_cancel_test-adrian.$(OBJEXT)
-@HAVE_SPEEX_TRUE@am__objects_26 = modules/echo-cancel/echo_cancel_test-speex.$(OBJEXT)
-am__objects_27 = modules/echo-cancel/echo_cancel_test-module-echo-cancel.$(OBJEXT) \
+@HAVE_SPEEX_TRUE@am__objects_28 = modules/echo-cancel/echo_cancel_test-speex.$(OBJEXT)
+am__objects_29 = modules/echo-cancel/echo_cancel_test-module-echo-cancel.$(OBJEXT) \
modules/echo-cancel/echo_cancel_test-null.$(OBJEXT) \
- $(am__objects_25) $(am__objects_26)
-am_echo_cancel_test_OBJECTS = $(am__objects_27)
-@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__objects_28 = modules/echo-cancel/echo_cancel_test-adrian-aec-orc-gen.$(OBJEXT)
-nodist_echo_cancel_test_OBJECTS = $(am__objects_28)
+ $(am__objects_27) $(am__objects_28)
+am_echo_cancel_test_OBJECTS = $(am__objects_29)
+@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@am__objects_30 = modules/echo-cancel/echo_cancel_test-adrian-aec-orc-gen.$(OBJEXT)
+nodist_echo_cancel_test_OBJECTS = $(am__objects_30)
echo_cancel_test_OBJECTS = $(am_echo_cancel_test_OBJECTS) \
$(nodist_echo_cancel_test_OBJECTS)
-am__DEPENDENCIES_14 = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_13) \
- $(am__DEPENDENCIES_10) $(am__append_139)
-echo_cancel_test_DEPENDENCIES = $(am__DEPENDENCIES_14)
+am__DEPENDENCIES_15 = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_14) \
+ $(am__DEPENDENCIES_10) $(am__append_143)
+echo_cancel_test_DEPENDENCIES = $(am__DEPENDENCIES_15)
echo_cancel_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(echo_cancel_test_CFLAGS) $(CFLAGS) \
@@ -2385,12 +2403,12 @@ mainloop_test_DEPENDENCIES = $(am__DEPENDENCIES_2) libpulse.la \
mainloop_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(mainloop_test_CFLAGS) \
$(CFLAGS) $(mainloop_test_LDFLAGS) $(LDFLAGS) -o $@
-am__objects_29 = tests/mainloop_test_glib-mainloop-test.$(OBJEXT)
-am_mainloop_test_glib_OBJECTS = $(am__objects_29)
+am__objects_31 = tests/mainloop_test_glib-mainloop-test.$(OBJEXT)
+am_mainloop_test_glib_OBJECTS = $(am__objects_31)
mainloop_test_glib_OBJECTS = $(am_mainloop_test_glib_OBJECTS)
-am__DEPENDENCIES_15 = $(am__DEPENDENCIES_2) libpulse.la \
+am__DEPENDENCIES_16 = $(am__DEPENDENCIES_2) libpulse.la \
libpulsecommon-@PA_MAJORMINOR@.la
-mainloop_test_glib_DEPENDENCIES = $(am__DEPENDENCIES_15) \
+mainloop_test_glib_DEPENDENCIES = $(am__DEPENDENCIES_16) \
$(am__DEPENDENCIES_1) libpulse-mainloop-glib.la
mainloop_test_glib_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
@@ -2521,7 +2539,7 @@ am__pulseaudio_SOURCES_DIST = daemon/caps.c daemon/caps.h \
daemon/dumpmodules.c daemon/dumpmodules.h \
daemon/ltdl-bind-now.c daemon/ltdl-bind-now.h daemon/main.c \
daemon/server-lookup.c daemon/server-lookup.h
-@HAVE_DBUS_TRUE@am__objects_30 = \
+@HAVE_DBUS_TRUE@am__objects_32 = \
@HAVE_DBUS_TRUE@ daemon/pulseaudio-server-lookup.$(OBJEXT)
am_pulseaudio_OBJECTS = daemon/pulseaudio-caps.$(OBJEXT) \
daemon/pulseaudio-cmdline.$(OBJEXT) \
@@ -2529,7 +2547,7 @@ am_pulseaudio_OBJECTS = daemon/pulseaudio-caps.$(OBJEXT) \
daemon/pulseaudio-daemon-conf.$(OBJEXT) \
daemon/pulseaudio-dumpmodules.$(OBJEXT) \
daemon/pulseaudio-ltdl-bind-now.$(OBJEXT) \
- daemon/pulseaudio-main.$(OBJEXT) $(am__objects_30)
+ daemon/pulseaudio-main.$(OBJEXT) $(am__objects_32)
pulseaudio_OBJECTS = $(am_pulseaudio_OBJECTS)
pulseaudio_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(pulseaudio_CFLAGS) \
@@ -2837,12 +2855,15 @@ am__depfiles_remade = daemon/$(DEPDIR)/cpulimit_test-cpulimit.Po \
modules/raop/$(DEPDIR)/libraop_la-raop-util.Plo \
modules/raop/$(DEPDIR)/module_raop_discover_la-module-raop-discover.Plo \
modules/raop/$(DEPDIR)/module_raop_sink_la-module-raop-sink.Plo \
- modules/rtp/$(DEPDIR)/headerlist.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-headerlist.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-sap.Plo \
+ modules/rtp/$(DEPDIR)/librtp_la-sdp.Plo \
modules/rtp/$(DEPDIR)/module_rtp_recv_la-module-rtp-recv.Plo \
modules/rtp/$(DEPDIR)/module_rtp_send_la-module-rtp-send.Plo \
- modules/rtp/$(DEPDIR)/rtp.Plo \
- modules/rtp/$(DEPDIR)/rtsp_client.Plo \
- modules/rtp/$(DEPDIR)/sap.Plo modules/rtp/$(DEPDIR)/sdp.Plo \
modules/x11/$(DEPDIR)/module_x11_bell_la-module-x11-bell.Plo \
modules/x11/$(DEPDIR)/module_x11_cork_request_la-module-x11-cork-request.Plo \
modules/x11/$(DEPDIR)/module_x11_publish_la-module-x11-publish.Plo \
@@ -3283,7 +3304,8 @@ DIST_SOURCES = $(am__libalsa_util_la_SOURCES_DIST) \
$(am__libpulsecore_remap_neon_la_SOURCES_DIST) \
$(am__libpulsecore_sconv_neon_la_SOURCES_DIST) \
$(libpulsedsp_la_SOURCES) $(libraop_la_SOURCES) \
- $(librtp_la_SOURCES) $(am__libwebrtc_util_la_SOURCES_DIST) \
+ $(am__librtp_la_SOURCES_DIST) \
+ $(am__libwebrtc_util_la_SOURCES_DIST) \
$(module_allow_passthrough_la_SOURCES) \
$(module_alsa_card_la_SOURCES) $(module_alsa_sink_la_SOURCES) \
$(module_alsa_source_la_SOURCES) \
@@ -3439,11 +3461,11 @@ am__dist_alsapaths_DATA_DIST = \
modules/alsa/mixer/paths/hdmi-output-5.conf \
modules/alsa/mixer/paths/hdmi-output-6.conf \
modules/alsa/mixer/paths/hdmi-output-7.conf \
- modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf \
- modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf \
- modules/alsa/mixer/paths/steelseries-arctis-7-input.conf \
- modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf \
- modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf
+ modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf \
+ modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf \
+ modules/alsa/mixer/paths/usb-gaming-headset-input.conf \
+ modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf \
+ modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf
am__dist_alsaprofilesets_DATA_DIST = \
modules/alsa/mixer/profile-sets/default.conf \
modules/alsa/mixer/profile-sets/force-speaker.conf \
@@ -3458,8 +3480,8 @@ am__dist_alsaprofilesets_DATA_DIST = \
modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf \
modules/alsa/mixer/profile-sets/kinect-audio.conf \
modules/alsa/mixer/profile-sets/sb-omni-surround-5.1.conf \
- modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf \
- modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf \
+ modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf \
+ modules/alsa/mixer/profile-sets/usb-gaming-headset.conf \
modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \
modules/alsa/mixer/profile-sets/cmedia-high-speed-true-hdaudio.conf
am__dist_udevrules_DATA_DIST = modules/alsa/90-pulseaudio.rules
@@ -3744,6 +3766,8 @@ GREP = @GREP@
GSETTINGS_CFLAGS = @GSETTINGS_CFLAGS@
GSETTINGS_DISABLE_SCHEMAS_COMPILE = @GSETTINGS_DISABLE_SCHEMAS_COMPILE@
GSETTINGS_LIBS = @GSETTINGS_LIBS@
+GSTREAMER_CFLAGS = @GSTREAMER_CFLAGS@
+GSTREAMER_LIBS = @GSTREAMER_LIBS@
GTK30_CFLAGS = @GTK30_CFLAGS@
GTK30_LIBS = @GTK30_LIBS@
HAVE_AF_UNIX = @HAVE_AF_UNIX@
@@ -3954,7 +3978,6 @@ prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
pulseconfdir = @pulseconfdir@
-runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
@@ -4049,7 +4072,7 @@ CLEANFILES = $(am__append_7) $(am__append_50) \
@HAVE_ORC_TRUE@cp_v_gen = $(cp_v_gen_$(V))
@HAVE_ORC_TRUE@cp_v_gen_ = $(cp_v_gen_$(AM_DEFAULT_VERBOSITY))
@HAVE_ORC_TRUE@cp_v_gen_0 = @echo " CP $@";
-ORC_SOURCE = pulsecore/svolume $(am__append_132)
+ORC_SOURCE = pulsecore/svolume $(am__append_136)
pulseaudio_SOURCES = daemon/caps.c daemon/caps.h daemon/cmdline.c \
daemon/cmdline.h daemon/cpulimit.c daemon/cpulimit.h \
daemon/daemon-conf.c daemon/daemon-conf.h daemon/dumpmodules.c \
@@ -4078,7 +4101,7 @@ pulseaudio_DEPENDENCIES = libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJ
# Utility programs #
###################################
bin_SCRIPTS = utils/pa-info $(am__append_13) $(am__append_17) \
- $(am__append_49) $(am__append_117)
+ $(am__append_49) $(am__append_121)
pacat_SOURCES = utils/pacat.c
pacat_LDADD = $(AM_LDADD) libpulse.la libpulsecommon-@PA_MAJORMINOR@.la $(LIBSNDFILE_LIBS)
pacat_CFLAGS = $(AM_CFLAGS) $(LIBSNDFILE_CFLAGS)
@@ -4622,7 +4645,7 @@ libpulsecore_foreign_la_CFLAGS = $(AM_CFLAGS) $(FOREIGN_CFLAGS)
modlibexec_LTLIBRARIES = libcli.la libprotocol-cli.la \
libprotocol-simple.la libprotocol-http.la \
libprotocol-native.la $(am__append_78) $(am__append_79) \
- $(am__append_80) $(am__append_81) $(am__append_84) \
+ $(am__append_80) $(am__append_81) $(am__append_88) \
module-cli.la module-cli-protocol-tcp.la \
module-simple-protocol-tcp.la module-null-sink.la \
module-null-source.la module-sine-source.la module-detect.la \
@@ -4644,16 +4667,16 @@ modlibexec_LTLIBRARIES = libcli.la libprotocol-cli.la \
module-switch-on-connect.la module-switch-on-port-available.la \
module-filter-apply.la module-filter-heuristics.la \
module-role-ducking.la module-allow-passthrough.la \
- $(am__append_85) $(am__append_86) $(am__append_87) \
- $(am__append_88) $(am__append_89) $(am__append_90) \
- $(am__append_91) $(am__append_92) $(am__append_93) \
- $(am__append_94) $(am__append_95) $(am__append_96) \
- $(am__append_97) $(am__append_98) $(am__append_99) \
- $(am__append_100) $(am__append_101) $(am__append_102) \
- $(am__append_103) $(am__append_105) $(am__append_107) \
- $(am__append_108) $(am__append_109) $(am__append_110) \
- $(am__append_111) $(am__append_112) $(am__append_113) \
- $(am__append_114) $(am__append_115) $(am__append_116)
+ $(am__append_89) $(am__append_90) $(am__append_91) \
+ $(am__append_92) $(am__append_93) $(am__append_94) \
+ $(am__append_95) $(am__append_96) $(am__append_97) \
+ $(am__append_98) $(am__append_99) $(am__append_100) \
+ $(am__append_101) $(am__append_102) $(am__append_103) \
+ $(am__append_104) $(am__append_105) $(am__append_106) \
+ $(am__append_107) $(am__append_109) $(am__append_111) \
+ $(am__append_112) $(am__append_113) $(am__append_114) \
+ $(am__append_115) $(am__append_116) $(am__append_117) \
+ $(am__append_118) $(am__append_119) $(am__append_120)
libprotocol_simple_la_SOURCES = pulsecore/protocol-simple.c pulsecore/protocol-simple.h
libprotocol_simple_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
libprotocol_simple_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
@@ -4676,15 +4699,15 @@ libprotocol_native_la_LIBADD = $(AM_LIBADD) \
@HAVE_ESOUND_TRUE@libprotocol_esound_la_SOURCES = pulsecore/protocol-esound.c pulsecore/protocol-esound.h pulsecore/esound.h
@HAVE_ESOUND_TRUE@libprotocol_esound_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
@HAVE_ESOUND_TRUE@libprotocol_esound_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.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_SOURCES = modules/rtp/rtp-common.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 $(am__append_84) $(am__append_87)
+librtp_la_CFLAGS = $(AM_CFLAGS) $(am__append_85)
librtp_la_LDFLAGS = $(AM_LDFLAGS) $(AM_LIBLDFLAGS) -avoid-version
-librtp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la libpulsecommon-@PA_MAJORMINOR@.la libpulse.la
+librtp_la_LIBADD = $(AM_LIBADD) libpulsecore-@PA_MAJORMINOR@.la \
+ libpulsecommon-@PA_MAJORMINOR@.la libpulse.la $(am__append_86)
libraop_la_SOURCES = \
modules/raop/raop-util.c modules/raop/raop-util.h \
modules/raop/raop-crypto.c modules/raop/raop-crypto.h \
@@ -4715,8 +4738,8 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMIN
@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/native-instruments-korecontroller.conf \
@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/kinect-audio.conf \
@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/sb-omni-surround-5.1.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf \
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf \
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/usb-gaming-headset.conf \
@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/dell-dock-tb16-usb-audio.conf \
@HAVE_ALSA_TRUE@ modules/alsa/mixer/profile-sets/cmedia-high-speed-true-hdaudio.conf
@@ -4759,11 +4782,11 @@ libavahi_wrap_la_LIBADD = $(AM_LIBADD) $(AVAHI_CFLAGS) libpulsecore-@PA_MAJORMIN
@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/hdmi-output-5.conf \
@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/hdmi-output-6.conf \
@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/hdmi-output-7.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-7-input.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf \
-@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf \
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf \
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/usb-gaming-headset-input.conf \
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf \
+@HAVE_ALSA_TRUE@ modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf
@HAVE_GSETTINGS_TRUE@gsettingsdataconvert_DATA = \
@HAVE_GSETTINGS_TRUE@ modules/gsettings/pulseaudio.convert
@@ -4921,10 +4944,10 @@ module_remap_source_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_remap_sourc
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) $(SERVER_CFLAGS) \
- -DPA_MODULE_NAME=module_ladspa_sink $(am__append_118)
+ -DPA_MODULE_NAME=module_ladspa_sink $(am__append_122)
module_ladspa_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
module_ladspa_sink_la_LIBADD = $(MODULE_LIBADD) $(LIBLTDL) \
- $(am__append_119)
+ $(am__append_123)
module_equalizer_sink_la_SOURCES = modules/module-equalizer-sink.c
module_equalizer_sink_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) $(DBUS_CFLAGS) $(FFTW_CFLAGS) -DPA_MODULE_NAME=module_equalizer_sink
module_equalizer_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
@@ -4946,9 +4969,9 @@ module_tunnel_sink_la_CFLAGS = -DTUNNEL_SINK=1 $(AM_CFLAGS) $(X11_CFLAGS) -DPA_M
module_tunnel_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
module_tunnel_sink_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
module_tunnel_source_la_SOURCES = modules/module-tunnel.c
-module_tunnel_source_la_LDFLAGS = $(MODULE_LDFLAGS) $(X11_CFLAGS)
+module_tunnel_source_la_LDFLAGS = $(MODULE_LDFLAGS)
module_tunnel_source_la_LIBADD = $(MODULE_LIBADD) $(X11_LIBS)
-module_tunnel_source_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_tunnel_source
+module_tunnel_source_la_CFLAGS = $(AM_CFLAGS) $(X11_CFLAGS) -DPA_MODULE_NAME=module_tunnel_source
module_loopback_la_SOURCES = modules/module-loopback.c
module_loopback_la_LDFLAGS = $(MODULE_LDFLAGS)
module_loopback_la_LIBADD = $(MODULE_LIBADD)
@@ -5016,12 +5039,12 @@ libalsa_util_la_SOURCES = modules/alsa/alsa-util.c \
modules/alsa/alsa-mixer.h modules/alsa/alsa-sink.c \
modules/alsa/alsa-sink.h modules/alsa/alsa-source.c \
modules/alsa/alsa-source.h modules/reserve-wrap.c \
- modules/reserve-wrap.h $(am__append_120) $(am__append_123)
+ modules/reserve-wrap.h $(am__append_124) $(am__append_127)
libalsa_util_la_LDFLAGS = -avoid-version
libalsa_util_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) \
- $(am__append_121) $(am__append_124)
+ $(am__append_125) $(am__append_128)
libalsa_util_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) \
- $(ASOUNDLIB_CFLAGS) $(am__append_122) $(am__append_125)
+ $(ASOUNDLIB_CFLAGS) $(am__append_126) $(am__append_129)
module_alsa_sink_la_SOURCES = modules/alsa/module-alsa-sink.c
module_alsa_sink_la_LDFLAGS = $(MODULE_LDFLAGS)
module_alsa_sink_la_LIBADD = $(MODULE_LIBADD) $(ASOUNDLIB_LIBS) libalsa-util.la
@@ -5128,17 +5151,17 @@ module_device_manager_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_device_ma
module_device_restore_la_SOURCES = modules/module-device-restore.c
module_device_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
module_device_restore_la_LIBADD = $(MODULE_LIBADD) \
- libprotocol-native.la $(am__append_126)
+ libprotocol-native.la $(am__append_130)
module_device_restore_la_CFLAGS = $(AM_CFLAGS) \
- -DPA_MODULE_NAME=module_device_restore $(am__append_127)
+ -DPA_MODULE_NAME=module_device_restore $(am__append_131)
# Stream volume/muted/device restore module
module_stream_restore_la_SOURCES = modules/module-stream-restore.c
module_stream_restore_la_LDFLAGS = $(MODULE_LDFLAGS)
module_stream_restore_la_LIBADD = $(MODULE_LIBADD) \
- libprotocol-native.la $(am__append_128)
+ libprotocol-native.la $(am__append_132)
module_stream_restore_la_CFLAGS = $(AM_CFLAGS) \
- -DPA_MODULE_NAME=module_stream_restore $(am__append_129)
+ -DPA_MODULE_NAME=module_stream_restore $(am__append_133)
# Card profile restore module
module_card_restore_la_SOURCES = modules/module-card-restore.c
@@ -5186,13 +5209,13 @@ module_suspend_on_idle_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_suspend_
module_echo_cancel_la_SOURCES = \
modules/echo-cancel/module-echo-cancel.c \
modules/echo-cancel/null.c modules/echo-cancel/echo-cancel.h \
- $(am__append_130) $(am__append_135)
+ $(am__append_134) $(am__append_139)
module_echo_cancel_la_LDFLAGS = $(MODULE_LDFLAGS)
-module_echo_cancel_la_LIBADD = $(MODULE_LIBADD) $(am__append_133) \
- $(am__append_137) $(am__append_139)
+module_echo_cancel_la_LIBADD = $(MODULE_LIBADD) $(am__append_137) \
+ $(am__append_141) $(am__append_143)
module_echo_cancel_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) \
- -DPA_MODULE_NAME=module_echo_cancel $(am__append_131) \
- $(am__append_134) $(am__append_136) $(am__append_138)
+ -DPA_MODULE_NAME=module_echo_cancel $(am__append_135) \
+ $(am__append_138) $(am__append_140) $(am__append_142)
@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@nodist_module_echo_cancel_la_SOURCES = \
@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@ modules/echo-cancel/adrian-aec-orc-gen.c \
@HAVE_ADRIAN_EC_TRUE@@HAVE_ORC_TRUE@ modules/echo-cancel/adrian-aec-orc-gen.h
@@ -5209,11 +5232,11 @@ module_echo_cancel_la_CFLAGS = $(AM_CFLAGS) $(SERVER_CFLAGS) \
module_rtp_send_la_SOURCES = modules/rtp/module-rtp-send.c
module_rtp_send_la_LDFLAGS = $(MODULE_LDFLAGS)
module_rtp_send_la_LIBADD = $(MODULE_LIBADD) librtp.la
-module_rtp_send_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_rtp_send
+module_rtp_send_la_CFLAGS = $(AM_CFLAGS) $(GSTREAMER_CFLAGS) -DPA_MODULE_NAME=module_rtp_send
module_rtp_recv_la_SOURCES = modules/rtp/module-rtp-recv.c
module_rtp_recv_la_LDFLAGS = $(MODULE_LDFLAGS)
module_rtp_recv_la_LIBADD = $(MODULE_LIBADD) librtp.la
-module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) -DPA_MODULE_NAME=module_rtp_recv
+module_rtp_recv_la_CFLAGS = $(AM_CFLAGS) $(GSTREAMER_CFLAGS) -DPA_MODULE_NAME=module_rtp_recv
# JACK
module_jackdbus_detect_la_SOURCES = modules/jack/module-jackdbus-detect.c
@@ -5291,7 +5314,7 @@ libbluez5_util_la_SOURCES = modules/bluetooth/bluez5-util.c \
modules/bluetooth/a2dp-codec-util.c \
modules/bluetooth/a2dp-codec-util.h \
modules/bluetooth/a2dp-codecs.h modules/bluetooth/rtp.h \
- $(am__append_140) $(am__append_141) \
+ $(am__append_144) $(am__append_145) \
modules/bluetooth/a2dp-codec-sbc.c
libbluez5_util_la_LDFLAGS = -avoid-version
libbluez5_util_la_LIBADD = $(MODULE_LIBADD) $(DBUS_LIBS) $(SBC_LIBS)
@@ -6276,15 +6299,19 @@ modules/rtp/$(am__dirstamp):
modules/rtp/$(DEPDIR)/$(am__dirstamp):
@$(MKDIR_P) modules/rtp/$(DEPDIR)
@: > modules/rtp/$(DEPDIR)/$(am__dirstamp)
-modules/rtp/rtp.lo: modules/rtp/$(am__dirstamp) \
+modules/rtp/librtp_la-rtp-common.lo: modules/rtp/$(am__dirstamp) \
modules/rtp/$(DEPDIR)/$(am__dirstamp)
-modules/rtp/sdp.lo: modules/rtp/$(am__dirstamp) \
+modules/rtp/librtp_la-sdp.lo: modules/rtp/$(am__dirstamp) \
modules/rtp/$(DEPDIR)/$(am__dirstamp)
-modules/rtp/sap.lo: modules/rtp/$(am__dirstamp) \
+modules/rtp/librtp_la-sap.lo: modules/rtp/$(am__dirstamp) \
modules/rtp/$(DEPDIR)/$(am__dirstamp)
-modules/rtp/rtsp_client.lo: modules/rtp/$(am__dirstamp) \
+modules/rtp/librtp_la-rtsp_client.lo: modules/rtp/$(am__dirstamp) \
modules/rtp/$(DEPDIR)/$(am__dirstamp)
-modules/rtp/headerlist.lo: modules/rtp/$(am__dirstamp) \
+modules/rtp/librtp_la-headerlist.lo: modules/rtp/$(am__dirstamp) \
+ modules/rtp/$(DEPDIR)/$(am__dirstamp)
+modules/rtp/librtp_la-rtp-gstreamer.lo: modules/rtp/$(am__dirstamp) \
+ modules/rtp/$(DEPDIR)/$(am__dirstamp)
+modules/rtp/librtp_la-rtp-native.lo: modules/rtp/$(am__dirstamp) \
modules/rtp/$(DEPDIR)/$(am__dirstamp)
librtp.la: $(librtp_la_OBJECTS) $(librtp_la_DEPENDENCIES) $(EXTRA_librtp_la_DEPENDENCIES)
@@ -7546,13 +7573,15 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@modules/raop/$(DEPDIR)/libraop_la-raop-util.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/raop/$(DEPDIR)/module_raop_discover_la-module-raop-discover.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/raop/$(DEPDIR)/module_raop_sink_la-module-raop-sink.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/headerlist.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-headerlist.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-sap.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/librtp_la-sdp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/module_rtp_recv_la-module-rtp-recv.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/module_rtp_send_la-module-rtp-send.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/rtp.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/rtsp_client.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/sap.Plo@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@modules/rtp/$(DEPDIR)/sdp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/x11/$(DEPDIR)/module_x11_bell_la-module-x11-bell.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/x11/$(DEPDIR)/module_x11_cork_request_la-module-x11-cork-request.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@modules/x11/$(DEPDIR)/module_x11_publish_la-module-x11-publish.Plo@am__quote@ # am--include-marker
@@ -9237,6 +9266,55 @@ modules/raop/libraop_la-raop-sink.lo: modules/raop/raop-sink.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libraop_la_CFLAGS) $(CFLAGS) -c -o modules/raop/libraop_la-raop-sink.lo `test -f 'modules/raop/raop-sink.c' || echo '$(srcdir)/'`modules/raop/raop-sink.c
+modules/rtp/librtp_la-rtp-common.lo: modules/rtp/rtp-common.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-rtp-common.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Tpo -c -o modules/rtp/librtp_la-rtp-common.lo `test -f 'modules/rtp/rtp-common.c' || echo '$(srcdir)/'`modules/rtp/rtp-common.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Tpo modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/rtp-common.c' object='modules/rtp/librtp_la-rtp-common.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-rtp-common.lo `test -f 'modules/rtp/rtp-common.c' || echo '$(srcdir)/'`modules/rtp/rtp-common.c
+
+modules/rtp/librtp_la-sdp.lo: modules/rtp/sdp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-sdp.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-sdp.Tpo -c -o modules/rtp/librtp_la-sdp.lo `test -f 'modules/rtp/sdp.c' || echo '$(srcdir)/'`modules/rtp/sdp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-sdp.Tpo modules/rtp/$(DEPDIR)/librtp_la-sdp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/sdp.c' object='modules/rtp/librtp_la-sdp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-sdp.lo `test -f 'modules/rtp/sdp.c' || echo '$(srcdir)/'`modules/rtp/sdp.c
+
+modules/rtp/librtp_la-sap.lo: modules/rtp/sap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-sap.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-sap.Tpo -c -o modules/rtp/librtp_la-sap.lo `test -f 'modules/rtp/sap.c' || echo '$(srcdir)/'`modules/rtp/sap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-sap.Tpo modules/rtp/$(DEPDIR)/librtp_la-sap.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/sap.c' object='modules/rtp/librtp_la-sap.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-sap.lo `test -f 'modules/rtp/sap.c' || echo '$(srcdir)/'`modules/rtp/sap.c
+
+modules/rtp/librtp_la-rtsp_client.lo: modules/rtp/rtsp_client.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-rtsp_client.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Tpo -c -o modules/rtp/librtp_la-rtsp_client.lo `test -f 'modules/rtp/rtsp_client.c' || echo '$(srcdir)/'`modules/rtp/rtsp_client.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Tpo modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/rtsp_client.c' object='modules/rtp/librtp_la-rtsp_client.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-rtsp_client.lo `test -f 'modules/rtp/rtsp_client.c' || echo '$(srcdir)/'`modules/rtp/rtsp_client.c
+
+modules/rtp/librtp_la-headerlist.lo: modules/rtp/headerlist.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-headerlist.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-headerlist.Tpo -c -o modules/rtp/librtp_la-headerlist.lo `test -f 'modules/rtp/headerlist.c' || echo '$(srcdir)/'`modules/rtp/headerlist.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-headerlist.Tpo modules/rtp/$(DEPDIR)/librtp_la-headerlist.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/headerlist.c' object='modules/rtp/librtp_la-headerlist.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-headerlist.lo `test -f 'modules/rtp/headerlist.c' || echo '$(srcdir)/'`modules/rtp/headerlist.c
+
+modules/rtp/librtp_la-rtp-gstreamer.lo: modules/rtp/rtp-gstreamer.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-rtp-gstreamer.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Tpo -c -o modules/rtp/librtp_la-rtp-gstreamer.lo `test -f 'modules/rtp/rtp-gstreamer.c' || echo '$(srcdir)/'`modules/rtp/rtp-gstreamer.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Tpo modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/rtp-gstreamer.c' object='modules/rtp/librtp_la-rtp-gstreamer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-rtp-gstreamer.lo `test -f 'modules/rtp/rtp-gstreamer.c' || echo '$(srcdir)/'`modules/rtp/rtp-gstreamer.c
+
+modules/rtp/librtp_la-rtp-native.lo: modules/rtp/rtp-native.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -MT modules/rtp/librtp_la-rtp-native.lo -MD -MP -MF modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Tpo -c -o modules/rtp/librtp_la-rtp-native.lo `test -f 'modules/rtp/rtp-native.c' || echo '$(srcdir)/'`modules/rtp/rtp-native.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Tpo modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='modules/rtp/rtp-native.c' object='modules/rtp/librtp_la-rtp-native.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librtp_la_CFLAGS) $(CFLAGS) -c -o modules/rtp/librtp_la-rtp-native.lo `test -f 'modules/rtp/rtp-native.c' || echo '$(srcdir)/'`modules/rtp/rtp-native.c
+
modules/module_allow_passthrough_la-module-allow-passthrough.lo: modules/module-allow-passthrough.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(module_allow_passthrough_la_CFLAGS) $(CFLAGS) -MT modules/module_allow_passthrough_la-module-allow-passthrough.lo -MD -MP -MF modules/$(DEPDIR)/module_allow_passthrough_la-module-allow-passthrough.Tpo -c -o modules/module_allow_passthrough_la-module-allow-passthrough.lo `test -f 'modules/module-allow-passthrough.c' || echo '$(srcdir)/'`modules/module-allow-passthrough.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) modules/$(DEPDIR)/module_allow_passthrough_la-module-allow-passthrough.Tpo modules/$(DEPDIR)/module_allow_passthrough_la-module-allow-passthrough.Plo
@@ -12121,13 +12199,15 @@ distclean: distclean-am
-rm -f modules/raop/$(DEPDIR)/libraop_la-raop-util.Plo
-rm -f modules/raop/$(DEPDIR)/module_raop_discover_la-module-raop-discover.Plo
-rm -f modules/raop/$(DEPDIR)/module_raop_sink_la-module-raop-sink.Plo
- -rm -f modules/rtp/$(DEPDIR)/headerlist.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-headerlist.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-sap.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-sdp.Plo
-rm -f modules/rtp/$(DEPDIR)/module_rtp_recv_la-module-rtp-recv.Plo
-rm -f modules/rtp/$(DEPDIR)/module_rtp_send_la-module-rtp-send.Plo
- -rm -f modules/rtp/$(DEPDIR)/rtp.Plo
- -rm -f modules/rtp/$(DEPDIR)/rtsp_client.Plo
- -rm -f modules/rtp/$(DEPDIR)/sap.Plo
- -rm -f modules/rtp/$(DEPDIR)/sdp.Plo
-rm -f modules/x11/$(DEPDIR)/module_x11_bell_la-module-x11-bell.Plo
-rm -f modules/x11/$(DEPDIR)/module_x11_cork_request_la-module-x11-cork-request.Plo
-rm -f modules/x11/$(DEPDIR)/module_x11_publish_la-module-x11-publish.Plo
@@ -12580,13 +12660,15 @@ maintainer-clean: maintainer-clean-am
-rm -f modules/raop/$(DEPDIR)/libraop_la-raop-util.Plo
-rm -f modules/raop/$(DEPDIR)/module_raop_discover_la-module-raop-discover.Plo
-rm -f modules/raop/$(DEPDIR)/module_raop_sink_la-module-raop-sink.Plo
- -rm -f modules/rtp/$(DEPDIR)/headerlist.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-headerlist.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtp-common.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtp-gstreamer.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtp-native.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-rtsp_client.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-sap.Plo
+ -rm -f modules/rtp/$(DEPDIR)/librtp_la-sdp.Plo
-rm -f modules/rtp/$(DEPDIR)/module_rtp_recv_la-module-rtp-recv.Plo
-rm -f modules/rtp/$(DEPDIR)/module_rtp_send_la-module-rtp-send.Plo
- -rm -f modules/rtp/$(DEPDIR)/rtp.Plo
- -rm -f modules/rtp/$(DEPDIR)/rtsp_client.Plo
- -rm -f modules/rtp/$(DEPDIR)/sap.Plo
- -rm -f modules/rtp/$(DEPDIR)/sdp.Plo
-rm -f modules/x11/$(DEPDIR)/module_x11_bell_la-module-x11-bell.Plo
-rm -f modules/x11/$(DEPDIR)/module_x11_cork_request_la-module-x11-cork-request.Plo
-rm -f modules/x11/$(DEPDIR)/module_x11_publish_la-module-x11-publish.Plo
diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c
index 33cf7a7..bcf7329 100644
--- a/src/daemon/daemon-conf.c
+++ b/src/daemon/daemon-conf.c
@@ -68,7 +68,8 @@ static const pa_daemon_conf default_conf = {
.realtime_priority = 5, /* Half of JACK's default rtprio */
.disallow_module_loading = false,
.disallow_exit = false,
- .flat_volumes = true,
+ .flat_volumes = false,
+ .rescue_streams = true,
.exit_idle_time = 20,
.scache_idle_time = 20,
.script_commands = NULL,
@@ -84,7 +85,8 @@ static const pa_daemon_conf default_conf = {
.avoid_resampling = false,
.disable_remixing = false,
.remixing_use_all_sink_channels = true,
- .disable_lfe_remixing = true,
+ .remixing_produce_lfe = false,
+ .remixing_consume_lfe = false,
.lfe_crossover_freq = 0,
.config_file = NULL,
.use_pid_file = true,
@@ -496,6 +498,48 @@ static int parse_rtprio(pa_config_parser_state *state) {
return 0;
}
+static int parse_disable_lfe_remix(pa_config_parser_state *state) {
+ pa_daemon_conf *c;
+ int k;
+
+ pa_assert(state);
+ c = state->data;
+
+ if ((k = pa_parse_boolean(state->rvalue)) < 0) {
+ pa_log("[%s:%u] Failed to parse boolean value: %s", state->filename, state->lineno, state->rvalue);
+ return -1;
+ }
+
+ c->remixing_produce_lfe = c->remixing_consume_lfe = !k;
+
+ pa_log("[%s:%u] Deprecated option 'disable-lfe-remixing' found.", state->filename, state->lineno);
+ pa_log("[%s:%u] Please migrate to 'remixing-produce-lfe' and 'remixing-consume-lfe', set both to '%s'.",
+ state->filename, state->lineno, pa_yes_no(c->remixing_produce_lfe));
+
+ return 0;
+}
+
+static int parse_enable_lfe_remix(pa_config_parser_state *state) {
+ pa_daemon_conf *c;
+ int k;
+
+ pa_assert(state);
+ c = state->data;
+
+ if ((k = pa_parse_boolean(state->rvalue)) < 0) {
+ pa_log("[%s:%u] Failed to parse boolean value: %s", state->filename, state->lineno, state->rvalue);
+ return -1;
+ }
+
+ c->remixing_produce_lfe = c->remixing_consume_lfe = k;
+
+ pa_log("[%s:%u] Deprecated option 'enable-lfe-remixing' found.", state->filename, state->lineno);
+ pa_log("[%s:%u] Please migrate to 'remixing-produce-lfe' and 'remixing-consume-lfe', set both to '%s'.",
+ state->filename, state->lineno, pa_yes_no(c->remixing_produce_lfe));
+
+ return 0;
+}
+
#ifdef HAVE_DBUS
static int parse_server_type(pa_config_parser_state *state) {
pa_daemon_conf *c;
@@ -537,6 +581,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL },
{ "enable-memfd", pa_config_parse_not_bool, &c->disable_memfd, NULL },
{ "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL },
+ { "rescue-streams", pa_config_parse_bool, &c->rescue_streams, NULL },
{ "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL },
{ "enable-deferred-volume", pa_config_parse_bool, &c->deferred_volume, NULL },
{ "exit-idle-time", pa_config_parse_int, &c->exit_idle_time, NULL },
@@ -565,8 +610,10 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) {
{ "enable-remixing", pa_config_parse_not_bool, &c->disable_remixing, NULL },
{ "remixing-use-all-sink-channels",
pa_config_parse_bool, &c->remixing_use_all_sink_channels, NULL },
- { "disable-lfe-remixing", pa_config_parse_bool, &c->disable_lfe_remixing, NULL },
- { "enable-lfe-remixing", pa_config_parse_not_bool, &c->disable_lfe_remixing, NULL },
+ { "disable-lfe-remixing", parse_disable_lfe_remix, c, NULL },
+ { "enable-lfe-remixing", parse_enable_lfe_remix, c, NULL },
+ { "remixing-produce-lfe", pa_config_parse_bool, &c->remixing_produce_lfe, NULL },
+ { "remixing-consume-lfe", pa_config_parse_bool, &c->remixing_consume_lfe, NULL },
{ "lfe-crossover-freq", pa_config_parse_unsigned, &c->lfe_crossover_freq, NULL },
{ "load-default-script-file", pa_config_parse_bool, &c->load_default_script_file, NULL },
{ "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL },
@@ -749,6 +796,7 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "cpu-limit = %s\n", pa_yes_no(!c->no_cpu_limit));
pa_strbuf_printf(s, "enable-shm = %s\n", pa_yes_no(!c->disable_shm));
pa_strbuf_printf(s, "flat-volumes = %s\n", pa_yes_no(c->flat_volumes));
+ pa_strbuf_printf(s, "rescue-streams = %s\n", pa_yes_no(c->rescue_streams));
pa_strbuf_printf(s, "lock-memory = %s\n", pa_yes_no(c->lock_memory));
pa_strbuf_printf(s, "exit-idle-time = %i\n", c->exit_idle_time);
pa_strbuf_printf(s, "scache-idle-time = %i\n", c->scache_idle_time);
@@ -761,7 +809,8 @@ char *pa_daemon_conf_dump(pa_daemon_conf *c) {
pa_strbuf_printf(s, "avoid-resampling = %s\n", pa_yes_no(c->avoid_resampling));
pa_strbuf_printf(s, "enable-remixing = %s\n", pa_yes_no(!c->disable_remixing));
pa_strbuf_printf(s, "remixing-use-all-sink-channels = %s\n", pa_yes_no(c->remixing_use_all_sink_channels));
- pa_strbuf_printf(s, "enable-lfe-remixing = %s\n", pa_yes_no(!c->disable_lfe_remixing));
+ pa_strbuf_printf(s, "remixing-produce-lfe = %s\n", pa_yes_no(c->remixing_produce_lfe));
+ pa_strbuf_printf(s, "remixing-consume-lfe = %s\n", pa_yes_no(c->remixing_consume_lfe));
pa_strbuf_printf(s, "lfe-crossover-freq = %u\n", c->lfe_crossover_freq);
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);
diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h
index 953ea33..fa713b9 100644
--- a/src/daemon/daemon-conf.h
+++ b/src/daemon/daemon-conf.h
@@ -70,12 +70,14 @@ typedef struct pa_daemon_conf {
avoid_resampling,
disable_remixing,
remixing_use_all_sink_channels,
- disable_lfe_remixing,
+ remixing_produce_lfe,
+ remixing_consume_lfe,
load_default_script_file,
disallow_exit,
log_meta,
log_time,
flat_volumes,
+ rescue_streams,
lock_memory,
deferred_volume;
pa_server_type_t local_server_type;
diff --git a/src/daemon/daemon.conf.in b/src/daemon/daemon.conf.in
index a955523..7409976 100644
--- a/src/daemon/daemon.conf.in
+++ b/src/daemon/daemon.conf.in
@@ -57,10 +57,13 @@ ifelse(@HAVE_DBUS@, 1, [dnl
; avoid-resampling = false
; enable-remixing = yes
; remixing-use-all-sink-channels = yes
-; enable-lfe-remixing = no
+; remixing-produce-lfe = no
+; remixing-consume-lfe = no
; lfe-crossover-freq = 0
-; flat-volumes = yes
+; flat-volumes = no
+
+; rescue-streams = yes
ifelse(@HAVE_SYS_RESOURCE_H@, 1, [dnl
; rlimit-fsize = -1
diff --git a/src/daemon/default.pa.in b/src/daemon/default.pa.in
index 14b6a6f..030334f 100755
--- a/src/daemon/default.pa.in
+++ b/src/daemon/default.pa.in
@@ -138,10 +138,6 @@ load-module module-gconf
### that look up the default sink/source get the right value
load-module module-default-device-restore
-### Automatically move streams to the default sink if the sink they are
-### connected to dies, similar for sources
-load-module module-rescue-streams
-
### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink
diff --git a/src/daemon/main.c b/src/daemon/main.c
index e96c86d..f1810c5 100644
--- a/src/daemon/main.c
+++ b/src/daemon/main.c
@@ -1056,11 +1056,13 @@ int main(int argc, char *argv[]) {
c->avoid_resampling = conf->avoid_resampling;
c->disable_remixing = conf->disable_remixing;
c->remixing_use_all_sink_channels = conf->remixing_use_all_sink_channels;
- c->disable_lfe_remixing = conf->disable_lfe_remixing;
+ c->remixing_produce_lfe = conf->remixing_produce_lfe;
+ c->remixing_consume_lfe = conf->remixing_consume_lfe;
c->deferred_volume = conf->deferred_volume;
c->running_as_daemon = conf->daemonize;
c->disallow_exit = conf->disallow_exit;
c->flat_volumes = conf->flat_volumes;
+ c->rescue_streams = conf->rescue_streams;
#ifdef HAVE_DBUS
c->server_type = conf->local_server_type;
#endif
diff --git a/src/daemon/meson.build b/src/daemon/meson.build
index 9bc3bf1..9c9f807 100644
--- a/src/daemon/meson.build
+++ b/src/daemon/meson.build
@@ -31,7 +31,7 @@ executable('pulseaudio',
include_directories : [configinc, topinc],
link_args : ['-ffast-math'],
link_with : [libpulsecore, libpulsecommon, libpulse],
- dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep],
+ dependencies : [ltdl_dep, cap_dep, dbus_dep, libsystemd_dep, dl_dep, libintl_dep],
c_args : pa_c_args,
)
diff --git a/src/daemon/start-pulseaudio-x11.in b/src/daemon/start-pulseaudio-x11.in
index 1b5f429..0e84315 100755
--- a/src/daemon/start-pulseaudio-x11.in
+++ b/src/daemon/start-pulseaudio-x11.in
@@ -19,17 +19,19 @@ set -e
if [ x"$DISPLAY" != x ] ; then
- @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY" > /dev/null
- @PACTL_BINARY@ load-module module-x11-cork-request "display=$DISPLAY" > /dev/null
+ @PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY xauthority=$XAUTHORITY" > /dev/null
+ @PACTL_BINARY@ load-module module-x11-cork-request "display=$DISPLAY xauthority=$XAUTHORITY" > /dev/null
+ # KDE plasma versions older than 5.17.0 use module-device-manager's routing API.
+ # Check for current plasma version and load module if it's necessary.
if [ x"$KDE_FULL_SESSION" = x"true" ]; then
- plasmaversion=`grep "X-KDE-PluginInfo-Version" $DESKTOP_SESSION.desktop | cut -d "=" -f2 | cut -d "." -f1,2 | tr -d "."`
- if [ "$plasmaversion" -lt "517" ]; then
+ plasmaversion="$(plasmashell -v 2>/dev/null | sed -n 's/^plasmashell \([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)/\1*1000000+\2*1000+\3/p' | head -1)"
+ if [ -n "$plasmaversion" ] && [ "$(($plasmaversion))" -lt "5017000" ]; then
@PACTL_BINARY@ load-module module-device-manager "do_routing=1" > /dev/null
fi
fi
if [ x"$SESSION_MANAGER" != x ] ; then
- @PACTL_BINARY@ load-module module-x11-xsmp "display=$DISPLAY session_manager=$SESSION_MANAGER" > /dev/null
+ @PACTL_BINARY@ load-module module-x11-xsmp "display=$DISPLAY xauthority=$XAUTHORITY session_manager=$SESSION_MANAGER" > /dev/null
fi
fi
diff --git a/src/daemon/system.pa.in b/src/daemon/system.pa.in
index b1a4a5c..73e39ec 100755
--- a/src/daemon/system.pa.in
+++ b/src/daemon/system.pa.in
@@ -52,10 +52,6 @@ load-module module-native-protocol-unix
### that look up the default sink/source get the right value
load-module module-default-device-restore
-### Automatically move streams to the default sink if the sink they are
-### connected to dies, similar for sources
-load-module module-rescue-streams
-
### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink
diff --git a/src/meson.build b/src/meson.build
index c9b71a4..832c0de 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -183,7 +183,7 @@ libpulsecommon = shared_library('pulsecommon-' + pa_version_major_minor,
install_dir : privlibdir,
dependencies : [
libm_dep, thread_dep, dl_dep, shm_dep, iconv_dep, sndfile_dep, dbus_dep,
- x11_dep, libsystemd_dep, glib_dep, gtk_dep, asyncns_dep
+ x11_dep, libsystemd_dep, glib_dep, gtk_dep, asyncns_dep, libintl_dep,
],
implicit_include_directories : false)
diff --git a/src/modules/alsa/90-pulseaudio.rules b/src/modules/alsa/90-pulseaudio.rules
index d857639..fa43cb8 100644
--- a/src/modules/alsa/90-pulseaudio.rules
+++ b/src/modules/alsa/90-pulseaudio.rules
@@ -109,15 +109,23 @@ ATTRS{idVendor}=="0763", ATTRS{idProduct}=="2012", ENV{PULSE_PROFILE_SET}="maudi
ATTRS{idVendor}=="045e", ATTRS{idProduct}=="02bb", ENV{PULSE_PROFILE_SET}="kinect-audio.conf"
ATTRS{idVendor}=="041e", ATTRS{idProduct}=="322c", ENV{PULSE_PROFILE_SET}="sb-omni-surround-5.1.conf"
ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="4014", ENV{PULSE_PROFILE_SET}="dell-dock-tb16-usb-audio.conf"
-ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1250", ENV{PULSE_PROFILE_SET}="steelseries-arctis-5-usb-audio.conf"
+
# ID 1038:12ad is for the 2018 refresh of the Arctis 7.
-# ID 1038:1294 is for Arctis Pro Wireless (which works with the Arctis 7
-# configuration).
-ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf"
-ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf"
-ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf"
-ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="steelseries-arctis-7-usb-audio.conf"
+# ID 1038:1294 is for Arctis Pro Wireless (which works with the Arctis 7 configuration).
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1260", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12ad", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1294", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1730", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
+# Lucidsound LS31
+ATTRS{idVendor}=="2f12", ATTRS{idProduct}=="0109", ENV{PULSE_PROFILE_SET}="usb-gaming-headset.conf"
+
+# ID 1038:1250 is for the Arctis 5
+# ID 1037:12aa is for the Arctis 5 2019
+# ID 1038:1252 is for the Arctis Pro 2019 edition
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1250", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf"
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="12aa", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf"
+ATTRS{idVendor}=="1038", ATTRS{idProduct}=="1252", ENV{PULSE_PROFILE_SET}="steelseries-arctis-common-usb-audio.conf"
ATTRS{idVendor}=="147a", ATTRS{idProduct}=="e055", ENV{PULSE_PROFILE_SET}="cmedia-high-speed-true-hdaudio.conf"
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index cd99a75..d184aec 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -107,13 +107,54 @@ struct description_map {
const char *description;
};
-pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name) {
+static char *alsa_id_str(char *dst, size_t dst_len, pa_alsa_mixer_id *id) {
+ if (id->index > 0) {
+ snprintf(dst, dst_len, "'%s',%d", id->name, id->index);
+ } else {
+ snprintf(dst, dst_len, "'%s'", id->name);
+ }
+ return dst;
+}
+
+static int alsa_id_decode(const char *src, char *name, int *index) {
+ char *idx, c;
+ int i;
+
+ *index = 0;
+ c = src[0];
+ /* Strip quotes in entries such as 'Speaker',1 or "Speaker",1 */
+ if (c == '\'' || c == '"') {
+ strcpy(name, src + 1);
+ for (i = 0; name[i] != '\0' && name[i] != c; i++);
+ idx = NULL;
+ if (name[i]) {
+ name[i] = '\0';
+ idx = strchr(name + i + 1, ',');
+ }
+ } else {
+ strcpy(name, src);
+ idx = strchr(name, ',');
+ }
+ if (idx == NULL)
+ return 0;
+ *idx = '\0';
+ idx++;
+ if (*idx < '0' || *idx > '9') {
+ pa_log("Element %s: index value is invalid", src);
+ return 1;
+ }
+ *index = atoi(idx);
+ return 0;
+}
+
+pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name, const char *name) {
pa_alsa_jack *jack;
pa_assert(name);
jack = pa_xnew0(pa_alsa_jack, 1);
jack->path = path;
+ jack->mixer_device_name = pa_xstrdup(mixer_device_name);
jack->name = pa_xstrdup(name);
jack->alsa_name = pa_sprintf_malloc("%s Jack", name);
jack->state_unplugged = PA_AVAILABLE_NO;
@@ -132,6 +173,7 @@ void pa_alsa_jack_free(pa_alsa_jack *jack) {
pa_xfree(jack->alsa_name);
pa_xfree(jack->name);
+ pa_xfree(jack->mixer_device_name);
pa_xfree(jack);
}
@@ -467,7 +509,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
unsigned short revents = 0;
int err, ret = 0;
- pd = pa_rtpoll_item_get_userdata(i);
+ pd = pa_rtpoll_item_get_work_userdata(i);
pa_assert_fp(pd);
pa_assert_fp(i == pd->poll_item);
@@ -547,8 +589,7 @@ int pa_alsa_set_mixer_rtpoll(struct pa_alsa_mixer_pdata *pd, snd_mixer_t *mixer,
pd->poll_item = i;
pd->mixer = mixer;
- pa_rtpoll_item_set_userdata(i, pd);
- pa_rtpoll_item_set_work_callback(i, rtpoll_work_cb);
+ pa_rtpoll_item_set_work_callback(i, rtpoll_work_cb, pd);
return 0;
}
@@ -642,6 +683,7 @@ static void decibel_fix_free(pa_alsa_decibel_fix *db_fix) {
pa_xfree(db_fix->name);
pa_xfree(db_fix->db_values);
+ pa_xfree(db_fix->key);
pa_xfree(db_fix);
}
@@ -657,7 +699,7 @@ static void element_free(pa_alsa_element *e) {
if (e->db_fix)
decibel_fix_free(e->db_fix);
- pa_xfree(e->alsa_name);
+ pa_xfree(e->alsa_id.name);
pa_xfree(e);
}
@@ -699,6 +741,12 @@ void pa_alsa_path_set_free(pa_alsa_path_set *ps) {
pa_xfree(ps);
}
+int pa_alsa_path_set_is_empty(pa_alsa_path_set *ps) {
+ if (ps && !pa_hashmap_isempty(ps->paths))
+ return 0;
+ return 1;
+}
+
static long to_alsa_dB(pa_volume_t v) {
return lround(pa_sw_volume_to_dB(v) * 100.0);
}
@@ -718,11 +766,11 @@ static pa_volume_t from_alsa_volume(long v, long min, long max) {
return (pa_volume_t) round(((double) (v - min) * PA_VOLUME_NORM) / (double) (max - min));
}
-#define SELEM_INIT(sid, name) \
- do { \
- snd_mixer_selem_id_alloca(&(sid)); \
- snd_mixer_selem_id_set_name((sid), (name)); \
- snd_mixer_selem_id_set_index((sid), 0); \
+#define SELEM_INIT(sid, aid) \
+ do { \
+ snd_mixer_selem_id_alloca(&(sid)); \
+ snd_mixer_selem_id_set_name((sid), (aid)->name); \
+ snd_mixer_selem_id_set_index((sid), (aid)->index); \
} while(false)
static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v) {
@@ -730,6 +778,7 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
snd_mixer_elem_t *me;
snd_mixer_selem_channel_id_t c;
pa_channel_position_mask_t mask = 0;
+ char buf[64];
unsigned k;
pa_assert(m);
@@ -737,9 +786,10 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
pa_assert(cm);
pa_assert(v);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return -1;
}
@@ -764,14 +814,16 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
if (value < e->db_fix->min_step) {
value = e->db_fix->min_step;
snd_mixer_selem_set_playback_volume(me, c, value);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_debug("Playback volume for element %s channel %i was below the dB fix limit. "
- "Volume reset to %0.2f dB.", e->alsa_name, c,
+ "Volume reset to %0.2f dB.", buf, c,
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
} else if (value > e->db_fix->max_step) {
value = e->db_fix->max_step;
snd_mixer_selem_set_playback_volume(me, c, value);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_debug("Playback volume for element %s channel %i was over the dB fix limit. "
- "Volume reset to %0.2f dB.", e->alsa_name, c,
+ "Volume reset to %0.2f dB.", buf, c,
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
}
@@ -792,14 +844,16 @@ static int element_get_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
if (value < e->db_fix->min_step) {
value = e->db_fix->min_step;
snd_mixer_selem_set_capture_volume(me, c, value);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_debug("Capture volume for element %s channel %i was below the dB fix limit. "
- "Volume reset to %0.2f dB.", e->alsa_name, c,
+ "Volume reset to %0.2f dB.", buf, c,
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
} else if (value > e->db_fix->max_step) {
value = e->db_fix->max_step;
snd_mixer_selem_set_capture_volume(me, c, value);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_debug("Capture volume for element %s channel %i was over the dB fix limit. "
- "Volume reset to %0.2f dB.", e->alsa_name, c,
+ "Volume reset to %0.2f dB.", buf, c,
e->db_fix->db_values[value - e->db_fix->min_step] / 100.0);
}
@@ -897,14 +951,16 @@ static int element_get_switch(pa_alsa_element *e, snd_mixer_t *m, bool *b) {
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *me;
snd_mixer_selem_channel_id_t c;
+ char buf[64];
pa_assert(m);
pa_assert(e);
pa_assert(b);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return -1;
}
@@ -1058,6 +1114,7 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
snd_mixer_elem_t *me;
snd_mixer_selem_channel_id_t c;
pa_channel_position_mask_t mask = 0;
+ char buf[64];
unsigned k;
pa_assert(m);
@@ -1066,9 +1123,10 @@ static int element_set_volume(pa_alsa_element *e, snd_mixer_t *m, const pa_chann
pa_assert(v);
pa_assert(pa_cvolume_compatible_with_channel_map(v, cm));
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return -1;
}
@@ -1251,14 +1309,16 @@ int pa_alsa_path_set_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_ma
static int element_set_switch(pa_alsa_element *e, snd_mixer_t *m, bool b) {
snd_mixer_elem_t *me;
snd_mixer_selem_id_t *sid;
+ char buf[64];
int r;
pa_assert(m);
pa_assert(e);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return -1;
}
@@ -1267,8 +1327,10 @@ static int element_set_switch(pa_alsa_element *e, snd_mixer_t *m, bool b) {
else
r = snd_mixer_selem_set_capture_switch_all(me, b);
- if (r < 0)
- pa_log_warn("Failed to set switch of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+ if (r < 0) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno));
+ }
return r;
}
@@ -1303,13 +1365,15 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
int r = 0;
long volume = -1;
bool volume_set = false;
+ char buf[64];
pa_assert(m);
pa_assert(e);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return -1;
}
@@ -1352,8 +1416,10 @@ static int element_set_constant_volume(pa_alsa_element *e, snd_mixer_t *m) {
r = snd_mixer_selem_set_capture_dB_all(me, 0, -1);
}
- if (r < 0)
- pa_log_warn("Failed to set volume of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+ if (r < 0) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to set volume of %s: %s", buf, pa_alsa_strerror(errno));
+ }
return r;
}
@@ -1531,6 +1597,7 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
int r;
bool is_mono;
pa_channel_position_t p;
+ char buf[64];
if (e->direction == PA_ALSA_DIRECTION_OUTPUT) {
if (!snd_mixer_selem_has_playback_volume(me)) {
@@ -1556,29 +1623,33 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
r = snd_mixer_selem_get_capture_volume_range(me, &e->min_volume, &e->max_volume);
if (r < 0) {
- pa_log_warn("Failed to get volume range of %s: %s", e->alsa_name, pa_alsa_strerror(r));
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to get volume range of %s: %s", buf, pa_alsa_strerror(r));
return false;
}
if (e->min_volume >= e->max_volume) {
- pa_log_warn("Your kernel driver is broken: it reports a volume range from %li to %li which makes no sense.",
- e->min_volume, e->max_volume);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Your kernel driver is broken for element %s: it reports a volume range from %li to %li which makes no sense.",
+ buf, e->min_volume, e->max_volume);
return false;
}
if (e->volume_use == PA_ALSA_VOLUME_CONSTANT && (e->min_volume > e->constant_volume || e->max_volume < e->constant_volume)) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_warn("Constant volume %li configured for element %s, but the available range is from %li to %li.",
- e->constant_volume, e->alsa_name, e->min_volume, e->max_volume);
+ e->constant_volume, buf, e->min_volume, e->max_volume);
return false;
}
if (e->db_fix && ((e->min_volume > e->db_fix->min_step) || (e->max_volume < e->db_fix->max_step))) {
- pa_log_warn("The step range of the decibel fix for element %s (%li-%li) doesn't fit to the "
- "real hardware range (%li-%li). Disabling the decibel fix.", e->alsa_name,
- e->db_fix->min_step, e->db_fix->max_step, e->min_volume, e->max_volume);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("The step range of the decibel fix for element %s (%li-%li) doesn't fit to the "
+ "real hardware range (%li-%li). Disabling the decibel fix.", buf,
+ e->db_fix->min_step, e->db_fix->max_step, e->min_volume, e->max_volume);
- decibel_fix_free(e->db_fix);
- e->db_fix = NULL;
+ decibel_fix_free(e->db_fix);
+ e->db_fix = NULL;
}
if (e->db_fix) {
@@ -1599,19 +1670,22 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
long max_dB_checked = 0;
if (element_ask_vol_dB(me, e->direction, e->min_volume, &min_dB_checked) < 0) {
- pa_log_warn("Failed to query the dB value for %s at volume level %li", e->alsa_name, e->min_volume);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->min_volume);
return false;
}
if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB_checked) < 0) {
- pa_log_warn("Failed to query the dB value for %s at volume level %li", e->alsa_name, e->max_volume);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to query the dB value for %s at volume level %li", buf, e->max_volume);
return false;
}
if (min_dB != min_dB_checked || max_dB != max_dB_checked) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_warn("Your kernel driver is broken: the reported dB range for %s (from %0.2f dB to %0.2f dB) "
"doesn't match the dB values at minimum and maximum volume levels: %0.2f dB at level %li, "
- "%0.2f dB at level %li.", e->alsa_name, min_dB / 100.0, max_dB / 100.0,
+ "%0.2f dB at level %li.", buf, min_dB / 100.0, max_dB / 100.0,
min_dB_checked / 100.0, e->min_volume, max_dB_checked / 100.0, e->max_volume);
return false;
}
@@ -1630,11 +1704,12 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
}
if (e->volume_limit >= 0) {
- if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume)
+ if (e->volume_limit <= e->min_volume || e->volume_limit > e->max_volume) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_warn("Volume limit for element %s of path %s is invalid: %li isn't within the valid range "
"%li-%li. The volume limit is ignored.",
- e->alsa_name, e->path->name, e->volume_limit, e->min_volume + 1, e->max_volume);
- else {
+ buf, e->path->name, e->volume_limit, e->min_volume + 1, e->max_volume);
+ } else {
e->max_volume = e->volume_limit;
if (e->has_dB) {
@@ -1642,7 +1717,8 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
e->db_fix->max_step = e->max_volume;
e->max_dB = ((double) e->db_fix->db_values[e->db_fix->max_step - e->db_fix->min_step]) / 100.0;
} else if (element_ask_vol_dB(me, e->direction, e->max_volume, &max_dB) < 0) {
- pa_log_warn("Failed to get dB value of %s: %s", e->alsa_name, pa_alsa_strerror(r));
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to get dB value of %s: %s", buf, pa_alsa_strerror(r));
e->has_dB = false;
} else
e->max_dB = ((double) max_dB) / 100.0;
@@ -1682,7 +1758,8 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
}
if (e->n_channels <= 0) {
- pa_log_warn("Volume element %s with no channels?", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Volume element %s with no channels?", buf);
return false;
} else if (e->n_channels > 2) {
/* FIXME: In some places code like this is used:
@@ -1696,7 +1773,8 @@ static bool element_probe_volume(pa_alsa_element *e, snd_mixer_elem_t *me) {
* Since the array size is fixed at 2, we obviously
* don't support elements with more than two
* channels... */
- pa_log_warn("Volume element %s has %u channels. That's too much! I can't handle that!", e->alsa_name, e->n_channels);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Volume element %s has %u channels. That's too much! I can't handle that!", buf, e->n_channels);
return false;
}
@@ -1734,7 +1812,7 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
pa_assert(e);
pa_assert(e->path);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
@@ -1837,7 +1915,7 @@ static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m)
j->append_pcm_to_name = false;
}
- has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL;
+ has_control = pa_alsa_mixer_find_card(m, j->alsa_name, 0) != NULL;
pa_alsa_jack_set_has_control(j, has_control);
if (j->has_control) {
@@ -1853,8 +1931,10 @@ static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m)
return 0;
}
-static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool prefixed) {
+pa_alsa_element * pa_alsa_element_get(pa_alsa_path *p, const char *section, bool prefixed) {
pa_alsa_element *e;
+ char *name;
+ int index;
pa_assert(p);
pa_assert(section);
@@ -1870,16 +1950,22 @@ static pa_alsa_element* element_get(pa_alsa_path *p, const char *section, bool p
if (strchr(section, ':'))
return NULL;
- if (p->last_element && pa_streq(p->last_element->alsa_name, section))
+ name = alloca(strlen(section) + 1);
+ if (alsa_id_decode(section, name, &index))
+ return NULL;
+
+ if (p->last_element && pa_streq(p->last_element->alsa_id.name, name) &&
+ p->last_element->alsa_id.index == index)
return p->last_element;
PA_LLIST_FOREACH(e, p->elements)
- if (pa_streq(e->alsa_name, section))
+ if (pa_streq(e->alsa_id.name, name) && e->alsa_id.index == index)
goto finish;
e = pa_xnew0(pa_alsa_element, 1);
e->path = p;
- e->alsa_name = pa_xstrdup(section);
+ e->alsa_id.name = pa_xstrdup(name);
+ e->alsa_id.index = index;
e->direction = p->direction;
e->volume_limit = -1;
@@ -1904,7 +1990,7 @@ static pa_alsa_jack* jack_get(pa_alsa_path *p, const char *section) {
if (pa_streq(j->name, section))
goto finish;
- j = pa_alsa_jack_new(p, section);
+ j = pa_alsa_jack_new(p, NULL, section);
PA_LLIST_INSERT_AFTER(pa_alsa_jack, p->jacks, p->last_jack, j);
finish:
@@ -1913,10 +1999,12 @@ finish:
}
static pa_alsa_option* option_get(pa_alsa_path *p, const char *section) {
- char *en;
+ char *en, *name;
const char *on;
pa_alsa_option *o;
pa_alsa_element *e;
+ size_t len;
+ int index;
if (!pa_startswith(section, "Option "))
return NULL;
@@ -1927,18 +2015,25 @@ static pa_alsa_option* option_get(pa_alsa_path *p, const char *section) {
if (!(on = strchr(section, ':')))
return NULL;
- en = pa_xstrndup(section, on - section);
+ len = on - section;
+ en = alloca(len + 1);
+ strncpy(en, section, len);
+ en[len] = '\0';
+
+ name = alloca(strlen(en) + 1);
+ if (alsa_id_decode(en, name, &index))
+ return NULL;
+
on++;
if (p->last_option &&
- pa_streq(p->last_option->element->alsa_name, en) &&
+ pa_streq(p->last_option->element->alsa_id.name, name) &&
+ p->last_option->element->alsa_id.index == index &&
pa_streq(p->last_option->alsa_name, on)) {
- pa_xfree(en);
return p->last_option;
}
- pa_assert_se(e = element_get(p, en, false));
- pa_xfree(en);
+ pa_assert_se(e = pa_alsa_element_get(p, en, false));
PA_LLIST_FOREACH(o, e->options)
if (pa_streq(o->alsa_name, on))
@@ -1967,7 +2062,7 @@ static int element_parse_switch(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] Switch makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -1998,7 +2093,7 @@ static int element_parse_volume(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] Volume makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -2034,7 +2129,7 @@ static int element_parse_enumeration(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] Enumeration makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -2126,7 +2221,7 @@ static int element_parse_required(pa_config_parser_state *state) {
p = state->userdata;
- e = element_get(p, state->section, true);
+ e = pa_alsa_element_get(p, state->section, true);
o = option_get(p, state->section);
j = jack_get(p, state->section);
if (!e && !o && !j) {
@@ -2192,7 +2287,7 @@ static int element_parse_direction(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -2218,7 +2313,7 @@ static int element_parse_direction_try_other(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] Direction makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -2241,7 +2336,7 @@ static int element_parse_volume_limit(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] volume-limit makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -2299,7 +2394,7 @@ static int element_parse_override_map(pa_config_parser_state *state) {
p = state->userdata;
- if (!(e = element_get(p, state->section, true))) {
+ if (!(e = pa_alsa_element_get(p, state->section, true))) {
pa_log("[%s:%u] Override map makes no sense in '%s'", state->filename, state->lineno, state->section);
return -1;
}
@@ -2394,14 +2489,16 @@ static int jack_parse_append_pcm_to_name(pa_config_parser_state *state) {
static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx) {
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *me;
+ char buf[64];
int r;
pa_assert(e);
pa_assert(m);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return -1;
}
@@ -2412,14 +2509,18 @@ static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx)
else
r = snd_mixer_selem_set_capture_switch_all(me, alsa_idx);
- if (r < 0)
- pa_log_warn("Failed to set switch of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+ if (r < 0) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to set switch of %s: %s", buf, pa_alsa_strerror(errno));
+ }
} else {
pa_assert(e->enumeration_use == PA_ALSA_ENUMERATION_SELECT);
- if ((r = snd_mixer_selem_set_enum_item(me, 0, alsa_idx)) < 0)
- pa_log_warn("Failed to set enumeration of %s: %s", e->alsa_name, pa_alsa_strerror(errno));
+ if ((r = snd_mixer_selem_set_enum_item(me, 0, alsa_idx)) < 0) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Failed to set enumeration of %s: %s", buf, pa_alsa_strerror(errno));
+ }
}
return r;
@@ -2463,6 +2564,7 @@ static int option_verify(pa_alsa_option *o) {
{ "output-speaker", N_("Speaker") },
{ "output-headphones", N_("Headphones") }
};
+ char buf[64];
pa_assert(o);
@@ -2473,14 +2575,16 @@ static int option_verify(pa_alsa_option *o) {
if (o->element->enumeration_use != PA_ALSA_ENUMERATION_SELECT &&
o->element->switch_use != PA_ALSA_SWITCH_SELECT) {
- pa_log("Element %s of option %s not set for select.", o->element->alsa_name, o->name);
+ alsa_id_str(buf, sizeof(buf), &o->element->alsa_id);
+ pa_log("Element %s of option %s not set for select.", buf, o->name);
return -1;
}
if (o->element->switch_use == PA_ALSA_SWITCH_SELECT &&
!pa_streq(o->alsa_name, "on") &&
!pa_streq(o->alsa_name, "off")) {
- pa_log("Switch %s options need be named off or on ", o->element->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &o->element->alsa_id);
+ pa_log("Switch %s options need be named off or on ", buf);
return -1;
}
@@ -2496,6 +2600,7 @@ static int option_verify(pa_alsa_option *o) {
static int element_verify(pa_alsa_element *e) {
pa_alsa_option *o;
+ char buf[64];
pa_assert(e);
@@ -2504,12 +2609,14 @@ static int element_verify(pa_alsa_element *e) {
(e->required_any != PA_ALSA_REQUIRED_IGNORE && e->required_any == e->required_absent) ||
(e->required_absent == PA_ALSA_REQUIRED_ANY && e->required_any != PA_ALSA_REQUIRED_IGNORE) ||
(e->required_absent == PA_ALSA_REQUIRED_ANY && e->required != PA_ALSA_REQUIRED_IGNORE)) {
- pa_log("Element %s cannot be required and absent at the same time.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log("Element %s cannot be required and absent at the same time.", buf);
return -1;
}
if (e->switch_use == PA_ALSA_SWITCH_SELECT && e->enumeration_use == PA_ALSA_ENUMERATION_SELECT) {
- pa_log("Element %s cannot set select for both switch and enumeration.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log("Element %s cannot set select for both switch and enumeration.", buf);
return -1;
}
@@ -2661,9 +2768,15 @@ fail:
pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction) {
pa_alsa_path *p;
pa_alsa_element *e;
+ char *name;
+ int index;
pa_assert(element);
+ name = alloca(strlen(element) + 1);
+ if (alsa_id_decode(element, name, &index))
+ return NULL;
+
p = pa_xnew0(pa_alsa_path, 1);
p->name = pa_xstrdup(element);
p->direction = direction;
@@ -2671,7 +2784,8 @@ pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t d
e = pa_xnew0(pa_alsa_element, 1);
e->path = p;
- e->alsa_name = pa_xstrdup(element);
+ e->alsa_id.name = pa_xstrdup(name);
+ e->alsa_id.index = index;
e->direction = direction;
e->volume_limit = -1;
@@ -2821,6 +2935,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m
double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX];
pa_channel_position_t t;
pa_channel_position_mask_t path_volume_channels = 0;
+ char buf[64];
pa_assert(p);
pa_assert(m);
@@ -2844,12 +2959,13 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m
}
PA_LLIST_FOREACH(e, p->elements) {
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
if (element_probe(e, m) < 0) {
p->supported = false;
- pa_log_debug("Probe of element '%s' failed.", e->alsa_name);
+ pa_log_debug("Probe of element %s failed.", buf);
return -1;
}
- pa_log_debug("Probe of element '%s' succeeded (volume=%d, switch=%d, enumeration=%d).", e->alsa_name, e->volume_use, e->switch_use, e->enumeration_use);
+ pa_log_debug("Probe of element %s succeeded (volume=%d, switch=%d, enumeration=%d).", buf, e->volume_use, e->switch_use, e->enumeration_use);
if (ignore_dB)
e->has_dB = false;
@@ -2885,13 +3001,13 @@ int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m
* which cannot do dB volumes, so we we need
* to 'neutralize' this slider */
e->volume_use = PA_ALSA_VOLUME_ZERO;
- pa_log_info("Zeroing volume of '%s' on path '%s'", e->alsa_name, p->name);
+ pa_log_info("Zeroing volume of %s on path '%s'", buf, p->name);
}
}
} else if (p->has_volume) {
/* We can't use this volume, so let's ignore it */
e->volume_use = PA_ALSA_VOLUME_IGNORE;
- pa_log_info("Ignoring volume of '%s' on path '%s' (missing dB info)", e->alsa_name, p->name);
+ pa_log_info("Ignoring volume of %s on path '%s' (missing dB info)", buf, p->name);
}
p->has_volume = true;
}
@@ -2955,11 +3071,14 @@ void pa_alsa_option_dump(pa_alsa_option *o) {
}
void pa_alsa_element_dump(pa_alsa_element *e) {
+ char buf[64];
+
pa_alsa_option *o;
pa_assert(e);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
pa_log_debug("Element %s, direction=%i, switch=%i, volume=%i, volume_limit=%li, enumeration=%i, required=%i, required_any=%i, required_absent=%i, mask=0x%llx, n_channels=%u, override_map=%s",
- e->alsa_name,
+ buf,
e->direction,
e->switch_use,
e->volume_use,
@@ -3009,14 +3128,16 @@ void pa_alsa_path_dump(pa_alsa_path *p) {
static void element_set_callback(pa_alsa_element *e, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata) {
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *me;
+ char buf[64];
pa_assert(e);
pa_assert(m);
pa_assert(cb);
- SELEM_INIT(sid, e->alsa_name);
+ SELEM_INIT(sid, &e->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", e->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &e->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return;
}
@@ -3082,6 +3203,8 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
char **pn = NULL, **en = NULL, **ie;
pa_alsa_decibel_fix *db_fix;
void *state, *state2;
+ char name[64];
+ int index;
pa_assert(m);
pa_assert(m->profile_set);
@@ -3161,9 +3284,18 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
if (je == ie)
continue;
+ if (strlen(*je) + 1 >= sizeof(name)) {
+ pa_log("Element identifier %s is too long!", *je);
+ continue;
+ }
+
+ if (alsa_id_decode(*je, name, &index))
+ continue;
+
e = pa_xnew0(pa_alsa_element, 1);
e->path = p;
- e->alsa_name = pa_xstrdup(*je);
+ e->alsa_id.name = pa_xstrdup(name);
+ e->alsa_id.index = index;
e->direction = direction;
e->required_absent = PA_ALSA_REQUIRED_ANY;
e->volume_limit = -1;
@@ -3184,7 +3316,8 @@ finish:
pa_alsa_element *e;
PA_LLIST_FOREACH(e, p->elements) {
- if (e->volume_use != PA_ALSA_VOLUME_IGNORE && pa_streq(db_fix->name, e->alsa_name)) {
+ if (e->volume_use != PA_ALSA_VOLUME_IGNORE && pa_streq(db_fix->name, e->alsa_id.name) &&
+ db_fix->index == e->alsa_id.index) {
/* The profile set that contains the dB fix may be freed
* before the element, so we have to copy the dB fix
* object. */
@@ -3257,6 +3390,8 @@ static bool enumeration_is_subset(pa_alsa_option *a_options, pa_alsa_option *b_o
* Compares two elements to see if a is a subset of b
*/
static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_t *m) {
+ char buf[64];
+
pa_assert(a);
pa_assert(b);
pa_assert(m);
@@ -3294,9 +3429,10 @@ static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *me;
- SELEM_INIT(sid, a->alsa_name);
+ SELEM_INIT(sid, &a->alsa_id);
if (!(me = snd_mixer_find_selem(m, sid))) {
- pa_log_warn("Element %s seems to have disappeared.", a->alsa_name);
+ alsa_id_str(buf, sizeof(buf), &a->alsa_id);
+ pa_log_warn("Element %s seems to have disappeared.", buf);
return false;
}
@@ -3326,8 +3462,9 @@ static bool element_is_subset(pa_alsa_element *a, pa_alsa_element *b, snd_mixer_
return false;
for (s = 0; s <= SND_MIXER_SCHN_LAST; s++)
if (a->masks[s][a->n_channels-1] != b->masks[s][b->n_channels-1]) {
+ alsa_id_str(buf, sizeof(buf), &a->alsa_id);
pa_log_debug("Element %s is not a subset - mask a: 0x%" PRIx64 ", mask b: 0x%" PRIx64 ", at channel %d",
- a->alsa_name, a->masks[s][a->n_channels-1], b->masks[s][b->n_channels-1], s);
+ buf, a->masks[s][a->n_channels-1], b->masks[s][b->n_channels-1], s);
return false;
}
}
@@ -3424,7 +3561,8 @@ static void path_set_condense(pa_alsa_path_set *ps, snd_mixer_t *m) {
break;
PA_LLIST_FOREACH(eb, p2->elements) {
- if (pa_streq(ea->alsa_name, eb->alsa_name)) {
+ if (pa_streq(ea->alsa_id.name, eb->alsa_id.name) &&
+ ea->alsa_id.index == eb->alsa_id.index) {
found_matching_element = true;
is_subset = element_is_subset(ea, eb, m);
break;
@@ -3601,22 +3739,30 @@ static pa_alsa_profile *profile_get(pa_alsa_profile_set *ps, const char *name) {
return p;
}
-static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const char *name) {
+static pa_alsa_decibel_fix *decibel_fix_get(pa_alsa_profile_set *ps, const char *alsa_id) {
pa_alsa_decibel_fix *db_fix;
+ char *name;
+ int index;
- if (!pa_startswith(name, "DecibelFix "))
+ if (!pa_startswith(alsa_id, "DecibelFix "))
return NULL;
- name += 11;
+ alsa_id += 11;
- if ((db_fix = pa_hashmap_get(ps->decibel_fixes, name)))
+ if ((db_fix = pa_hashmap_get(ps->decibel_fixes, alsa_id)))
return db_fix;
+ name = alloca(strlen(alsa_id) + 1);
+ if (alsa_id_decode(alsa_id, name, &index))
+ return NULL;
+
db_fix = pa_xnew0(pa_alsa_decibel_fix, 1);
db_fix->profile_set = ps;
db_fix->name = pa_xstrdup(name);
+ db_fix->index = index;
+ db_fix->key = pa_xstrdup(alsa_id);
- pa_hashmap_put(ps->decibel_fixes, db_fix->name, db_fix);
+ pa_hashmap_put(ps->decibel_fixes, db_fix->key, db_fix);
return db_fix;
}
@@ -3840,6 +3986,24 @@ static int mapping_parse_fallback(pa_config_parser_state *state) {
return 0;
}
+static int mapping_parse_intended_roles(pa_config_parser_state *state) {
+ pa_alsa_profile_set *ps;
+ pa_alsa_mapping *m;
+
+ pa_assert(state);
+
+ ps = state->userdata;
+
+ if (!(m = pa_alsa_mapping_get(ps, state->section))) {
+ pa_log("[%s:%u] %s invalid in section %s", state->filename, state->lineno, state->lvalue, state->section);
+ return -1;
+ }
+
+ pa_proplist_sets(m->proplist, PA_PROP_DEVICE_INTENDED_ROLES, state->rvalue);
+
+ return 0;
+}
+
static int profile_parse_mappings(pa_config_parser_state *state) {
pa_alsa_profile_set *ps;
@@ -4004,7 +4168,8 @@ fail:
}
static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
- pa_alsa_direction_t direction, pa_hashmap *used_paths) {
+ pa_alsa_direction_t direction, pa_hashmap *used_paths,
+ pa_hashmap *mixers) {
pa_alsa_path *p;
void *state;
@@ -4029,7 +4194,7 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
pa_assert(pcm_handle);
- mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL);
+ mixer_handle = pa_alsa_open_mixer_for_pcm(mixers, pcm_handle, true);
if (!mixer_handle) {
/* Cannot open mixer, remove all entries */
pa_hashmap_remove_all(ps->paths);
@@ -4047,9 +4212,6 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
path_set_condense(ps, mixer_handle);
path_set_make_path_descriptions_unique(ps);
- if (mixer_handle)
- snd_mixer_close(mixer_handle);
-
PA_HASHMAP_FOREACH(p, ps->paths, state)
pa_hashmap_put(used_paths, p, p);
@@ -4431,6 +4593,7 @@ pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel
{ "element-output", mapping_parse_element, NULL, NULL },
{ "direction", mapping_parse_direction, NULL, NULL },
{ "exact-channels", mapping_parse_exact_channels, NULL, NULL },
+ { "intended-roles", mapping_parse_intended_roles, NULL, NULL },
/* Shared by [Mapping ...] and [Profile ...] */
{ "description", mapping_parse_description, NULL, NULL },
@@ -4628,6 +4791,7 @@ static void mapping_query_hw_device(pa_alsa_mapping *mapping, snd_pcm_t *pcm) {
void pa_alsa_profile_set_probe(
pa_alsa_profile_set *ps,
+ pa_hashmap *mixers,
const char *dev_id,
const pa_sample_spec *ss,
unsigned default_n_fragments,
@@ -4757,14 +4921,14 @@ void pa_alsa_profile_set_probe(
PA_IDXSET_FOREACH(m, p->output_mappings, idx)
if (m->output_pcm) {
found_output |= !p->fallback_output;
- mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT, used_paths);
+ mapping_paths_probe(m, p, PA_ALSA_DIRECTION_OUTPUT, used_paths, mixers);
}
if (p->input_mappings)
PA_IDXSET_FOREACH(m, p->input_mappings, idx)
if (m->input_pcm) {
found_input |= !p->fallback_input;
- mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT, used_paths);
+ mapping_paths_probe(m, p, PA_ALSA_DIRECTION_INPUT, used_paths, mixers);
}
}
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 65b0711..df739cc 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -32,8 +32,10 @@
#include <pulsecore/rtpoll.h>
typedef struct pa_alsa_fdlist pa_alsa_fdlist;
+typedef struct pa_alsa_mixer pa_alsa_mixer;
typedef struct pa_alsa_mixer_pdata pa_alsa_mixer_pdata;
typedef struct pa_alsa_setting pa_alsa_setting;
+typedef struct pa_alsa_mixer_id pa_alsa_mixer_id;
typedef struct pa_alsa_option pa_alsa_option;
typedef struct pa_alsa_element pa_alsa_element;
typedef struct pa_alsa_jack pa_alsa_jack;
@@ -97,6 +99,20 @@ struct pa_alsa_setting {
unsigned priority;
};
+/* An entry for one ALSA mixer */
+struct pa_alsa_mixer {
+ snd_mixer_t *mixer_handle;
+ int card_index;
+ pa_alsa_fdlist *fdl;
+ bool used_for_probe_only:1;
+};
+
+/* ALSA mixer element identifier */
+struct pa_alsa_mixer_id {
+ char *name;
+ int index;
+};
+
/* An option belongs to an element and refers to one enumeration item
* of the element is an enumeration item, or a switch status if the
* element is a switch item. */
@@ -123,7 +139,7 @@ struct pa_alsa_element {
pa_alsa_path *path;
PA_LLIST_FIELDS(pa_alsa_element);
- char *alsa_name;
+ struct pa_alsa_mixer_id alsa_id;
pa_alsa_direction_t direction;
pa_alsa_switch_use_t switch_use;
@@ -158,6 +174,9 @@ struct pa_alsa_jack {
pa_alsa_path *path;
PA_LLIST_FIELDS(pa_alsa_jack);
+ snd_mixer_t *mixer_handle;
+ char *mixer_device_name;
+
char *name; /* E g "Headphone" */
char *alsa_name; /* E g "Headphone Jack" */
bool has_control; /* is the jack itself present? */
@@ -175,7 +194,7 @@ struct pa_alsa_jack {
bool append_pcm_to_name;
};
-pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name);
+pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *mixer_device_name, const char *name);
void pa_alsa_jack_free(pa_alsa_jack *jack);
void pa_alsa_jack_set_has_control(pa_alsa_jack *jack, bool has_control);
void pa_alsa_jack_set_plugged_in(pa_alsa_jack *jack, bool plugged_in);
@@ -194,6 +213,7 @@ struct pa_alsa_path {
char *description;
unsigned priority;
bool autodetect_eld_device;
+ pa_alsa_mixer *eld_mixer_handle;
int eld_device;
pa_proplist *proplist;
@@ -237,6 +257,7 @@ void pa_alsa_element_dump(pa_alsa_element *e);
pa_alsa_path *pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction);
pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction);
+pa_alsa_element *pa_alsa_element_get(pa_alsa_path *p, const char *section, bool prefixed);
int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB);
void pa_alsa_path_dump(pa_alsa_path *p);
int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
@@ -251,6 +272,7 @@ pa_alsa_path_set *pa_alsa_path_set_new(pa_alsa_mapping *m, pa_alsa_direction_t d
void pa_alsa_path_set_dump(pa_alsa_path_set *s);
void pa_alsa_path_set_set_callback(pa_alsa_path_set *ps, snd_mixer_t *m, snd_mixer_elem_callback_t cb, void *userdata);
void pa_alsa_path_set_free(pa_alsa_path_set *s);
+int pa_alsa_path_set_is_empty(pa_alsa_path_set *s);
struct pa_alsa_mapping {
pa_alsa_profile_set *profile_set;
@@ -315,9 +337,12 @@ struct pa_alsa_profile {
};
struct pa_alsa_decibel_fix {
+ char *key;
+
pa_alsa_profile_set *profile_set;
char *name; /* Alsa volume element name. */
+ int index; /* Alsa volume element index. */
long min_step;
long max_step;
@@ -348,13 +373,11 @@ void pa_alsa_decibel_fix_dump(pa_alsa_decibel_fix *db_fix);
pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name);
pa_alsa_profile_set* pa_alsa_profile_set_new(const char *fname, const pa_channel_map *bonus);
-void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec);
+void pa_alsa_profile_set_probe(pa_alsa_profile_set *ps, pa_hashmap *mixers, const char *dev_id, const pa_sample_spec *ss, unsigned default_n_fragments, unsigned default_fragment_size_msec);
void pa_alsa_profile_set_free(pa_alsa_profile_set *s);
void pa_alsa_profile_set_dump(pa_alsa_profile_set *s);
void pa_alsa_profile_set_drop_unsupported(pa_alsa_profile_set *s);
-snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device);
-
pa_alsa_fdlist *pa_alsa_fdlist_new(void);
void pa_alsa_fdlist_free(pa_alsa_fdlist *fdl);
int pa_alsa_fdlist_set_handle(pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, snd_hctl_t *hctl_handle, pa_mainloop_api* m);
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 4b46708..042d4df 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -105,6 +105,7 @@ struct userdata {
char *paths_dir;
pa_alsa_fdlist *mixer_fdl;
pa_alsa_mixer_pdata *mixer_pd;
+ pa_hashmap *mixers;
snd_mixer_t *mixer_handle;
pa_alsa_path_set *mixer_path_set;
pa_alsa_path *mixer_path;
@@ -1266,7 +1267,7 @@ static void sync_mixer(struct userdata *u, pa_device_port *port) {
/* port may be NULL, because if we use a synthesized mixer path, then the
* sink has no ports. */
- if (port) {
+ if (port && !u->ucm_context) {
pa_alsa_port_data *data;
data = PA_DEVICE_PORT_DATA(port);
@@ -1598,7 +1599,7 @@ static void sink_set_mute_cb(pa_sink *s) {
static void mixer_volume_init(struct userdata *u) {
pa_assert(u);
- if (!u->mixer_path->has_volume) {
+ if (!u->mixer_path || !u->mixer_path->has_volume) {
pa_sink_set_write_volume_callback(u->sink, NULL);
pa_sink_set_get_volume_callback(u->sink, NULL);
pa_sink_set_set_volume_callback(u->sink, NULL);
@@ -1633,7 +1634,7 @@ static void mixer_volume_init(struct userdata *u) {
pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported");
}
- if (!u->mixer_path->has_mute) {
+ if (!u->mixer_path || !u->mixer_path->has_mute) {
pa_sink_set_get_mute_callback(u->sink, NULL);
pa_sink_set_set_mute_callback(u->sink, NULL);
pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
@@ -1646,11 +1647,21 @@ static void mixer_volume_init(struct userdata *u) {
static int sink_set_port_ucm_cb(pa_sink *s, pa_device_port *p) {
struct userdata *u = s->userdata;
+ pa_alsa_ucm_port_data *data;
pa_assert(u);
pa_assert(p);
pa_assert(u->ucm_context);
+ data = PA_DEVICE_PORT_DATA(p);
+ pa_assert_se(u->mixer_path = data->path);
+ mixer_volume_init(u);
+
+ if (s->flags & PA_SINK_DEFERRED_VOLUME)
+ pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_SYNC_MIXER, p, 0, NULL);
+ else
+ sync_mixer(u, p);
+
return pa_alsa_ucm_set_port(u->ucm_context, p, true);
}
@@ -1661,6 +1672,7 @@ static int sink_set_port_cb(pa_sink *s, pa_device_port *p) {
pa_assert(u);
pa_assert(p);
pa_assert(u->mixer_handle);
+ pa_assert(!u->ucm_context);
data = PA_DEVICE_PORT_DATA(p);
pa_assert_se(u->mixer_path = data->path);
@@ -2071,10 +2083,24 @@ static void set_sink_name(pa_sink_new_data *data, pa_modargs *ma, const char *de
}
static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) {
+ const char *mdev;
+
if (!mapping && !element)
return;
- if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) {
+ if (!element && mapping && pa_alsa_path_set_is_empty(mapping->output_path_set))
+ return;
+
+ u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
+ NULL, (pa_free_cb_t) pa_alsa_mixer_free);
+
+ mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device");
+ if (mdev) {
+ u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, true);
+ } else {
+ u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->mixers, u->pcm_handle, true);
+ }
+ if (!u->mixer_handle) {
pa_log_info("Failed to find a working mixer device.");
return;
}
@@ -2089,8 +2115,9 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
pa_alsa_path_dump(u->mixer_path);
- } else if (!(u->mixer_path_set = mapping->output_path_set))
- goto fail;
+ } else {
+ u->mixer_path_set = mapping->output_path_set;
+ }
return;
@@ -2101,10 +2128,9 @@ fail:
u->mixer_path = NULL;
}
- if (u->mixer_handle) {
- snd_mixer_close(u->mixer_handle);
- u->mixer_handle = NULL;
- }
+ u->mixer_handle = NULL;
+ pa_hashmap_free(u->mixers);
+ u->mixers = NULL;
}
static int setup_mixer(struct userdata *u, bool ignore_dB) {
@@ -2116,16 +2142,31 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
return 0;
if (u->sink->active_port) {
- pa_alsa_port_data *data;
+ if (!u->ucm_context) {
+ pa_alsa_port_data *data;
+
+ /* We have a list of supported paths, so let's activate the
+ * one that has been chosen as active */
- /* We have a list of supported paths, so let's activate the
- * one that has been chosen as active */
+ data = PA_DEVICE_PORT_DATA(u->sink->active_port);
+ u->mixer_path = data->path;
- data = PA_DEVICE_PORT_DATA(u->sink->active_port);
- u->mixer_path = data->path;
+ pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted);
+ } else {
+ pa_alsa_ucm_port_data *data;
+
+ /* First activate the port on the UCM side */
+ if (pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0)
+ return -1;
- pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->sink->muted);
+ data = PA_DEVICE_PORT_DATA(u->sink->active_port);
+ /* Now activate volume controls, if any */
+ if (data->path) {
+ u->mixer_path = data->path;
+ pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, u->sink->muted);
+ }
+ }
} else {
if (!u->mixer_path && u->mixer_path_set)
@@ -2135,7 +2176,6 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
/* Hmm, we have only a single path, then let's activate it */
pa_alsa_path_select(u->mixer_path, u->mixer_path->settings, u->mixer_handle, u->sink->muted);
-
} else
return 0;
}
@@ -2466,8 +2506,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
/* ALSA might tweak the sample spec, so recalculate the frame size */
frame_size = pa_frame_size(&ss);
- if (!u->ucm_context)
- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
pa_sink_new_data_init(&data);
data.driver = driver;
@@ -2523,10 +2562,14 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
goto fail;
}
- if (u->ucm_context)
- pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card);
- else if (u->mixer_path_set)
- pa_alsa_add_ports(&data, u->mixer_path_set, card);
+ if (u->ucm_context) {
+ pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, true, card, u->pcm_handle, ignore_dB);
+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
+ } else {
+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
+ if (u->mixer_path_set)
+ pa_alsa_add_ports(&data, u->mixer_path_set, card);
+ }
u->sink = pa_sink_new(m->core, &data, PA_SINK_HARDWARE | PA_SINK_LATENCY | (u->use_tsched ? PA_SINK_DYNAMIC_LATENCY : 0) |
(set_formats ? PA_SINK_SET_FORMATS : 0));
@@ -2598,10 +2641,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
if (update_sw_params(u, false) < 0)
goto fail;
- if (u->ucm_context) {
- if (u->sink->active_port && pa_alsa_ucm_set_port(u->ucm_context, u->sink->active_port, true) < 0)
- goto fail;
- } else if (setup_mixer(u, ignore_dB) < 0)
+ if (setup_mixer(u, ignore_dB) < 0)
goto fail;
pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
@@ -2666,7 +2706,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
* pa_sink_suspend() between pa_sink_new() and pa_sink_put() would
* otherwise work, but currently pa_sink_suspend() will crash if
* pa_sink_put() hasn't been called. */
- if (u->sink->active_port) {
+ if (u->sink->active_port && !u->ucm_context) {
pa_alsa_port_data *port_data;
port_data = PA_DEVICE_PORT_DATA(u->sink->active_port);
@@ -2725,11 +2765,12 @@ static void userdata_free(struct userdata *u) {
if (u->mixer_fdl)
pa_alsa_fdlist_free(u->mixer_fdl);
- if (u->mixer_path && !u->mixer_path_set)
+ /* Only free the mixer_path if the sink owns it */
+ if (u->mixer_path && !u->mixer_path_set && !u->ucm_context)
pa_alsa_path_free(u->mixer_path);
- if (u->mixer_handle)
- snd_mixer_close(u->mixer_handle);
+ if (u->mixers)
+ pa_hashmap_free(u->mixers);
if (u->smoother)
pa_smoother_free(u->smoother);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index c8bf649..104de4e 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -93,6 +93,7 @@ struct userdata {
char *paths_dir;
pa_alsa_fdlist *mixer_fdl;
pa_alsa_mixer_pdata *mixer_pd;
+ pa_hashmap *mixers;
snd_mixer_t *mixer_handle;
pa_alsa_path_set *mixer_path_set;
pa_alsa_path *mixer_path;
@@ -1137,7 +1138,7 @@ static void sync_mixer(struct userdata *u, pa_device_port *port) {
/* port may be NULL, because if we use a synthesized mixer path, then the
* source has no ports. */
- if (port) {
+ if (port && !u->ucm_context) {
pa_alsa_port_data *data;
data = PA_DEVICE_PORT_DATA(port);
@@ -1469,7 +1470,7 @@ static void source_set_mute_cb(pa_source *s) {
static void mixer_volume_init(struct userdata *u) {
pa_assert(u);
- if (!u->mixer_path->has_volume) {
+ if (!u->mixer_path || !u->mixer_path->has_volume) {
pa_source_set_write_volume_callback(u->source, NULL);
pa_source_set_get_volume_callback(u->source, NULL);
pa_source_set_set_volume_callback(u->source, NULL);
@@ -1504,7 +1505,7 @@ static void mixer_volume_init(struct userdata *u) {
pa_log_info("Using hardware volume control. Hardware dB scale %s.", u->mixer_path->has_dB ? "supported" : "not supported");
}
- if (!u->mixer_path->has_mute) {
+ if (!u->mixer_path || !u->mixer_path->has_mute) {
pa_source_set_get_mute_callback(u->source, NULL);
pa_source_set_set_mute_callback(u->source, NULL);
pa_log_info("Driver does not support hardware mute control, falling back to software mute control.");
@@ -1517,11 +1518,21 @@ static void mixer_volume_init(struct userdata *u) {
static int source_set_port_ucm_cb(pa_source *s, pa_device_port *p) {
struct userdata *u = s->userdata;
+ pa_alsa_ucm_port_data *data;
pa_assert(u);
pa_assert(p);
pa_assert(u->ucm_context);
+ data = PA_DEVICE_PORT_DATA(p);
+ pa_assert_se(u->mixer_path = data->path);
+ mixer_volume_init(u);
+
+ if (s->flags & PA_SOURCE_DEFERRED_VOLUME)
+ pa_asyncmsgq_send(u->source->asyncmsgq, PA_MSGOBJECT(u->source), SOURCE_MESSAGE_SYNC_MIXER, p, 0, NULL);
+ else
+ sync_mixer(u, p);
+
return pa_alsa_ucm_set_port(u->ucm_context, p, false);
}
@@ -1532,6 +1543,7 @@ static int source_set_port_cb(pa_source *s, pa_device_port *p) {
pa_assert(u);
pa_assert(p);
pa_assert(u->mixer_handle);
+ pa_assert(!u->ucm_context);
data = PA_DEVICE_PORT_DATA(p);
pa_assert_se(u->mixer_path = data->path);
@@ -1777,10 +1789,24 @@ static void set_source_name(pa_source_new_data *data, pa_modargs *ma, const char
}
static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char *element, bool ignore_dB) {
+ const char *mdev;
+
if (!mapping && !element)
return;
- if (!(u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->pcm_handle, &u->control_device))) {
+ if (!element && mapping && pa_alsa_path_set_is_empty(mapping->input_path_set))
+ return;
+
+ u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
+ NULL, (pa_free_cb_t) pa_alsa_mixer_free);
+
+ mdev = pa_proplist_gets(mapping->proplist, "alsa.mixer_device");
+ if (mdev) {
+ u->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, mdev, false);
+ } else {
+ u->mixer_handle = pa_alsa_open_mixer_for_pcm(u->mixers, u->pcm_handle, false);
+ }
+ if (!u->mixer_handle) {
pa_log_info("Failed to find a working mixer device.");
return;
}
@@ -1795,8 +1821,9 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
pa_alsa_path_dump(u->mixer_path);
- } else if (!(u->mixer_path_set = mapping->input_path_set))
- goto fail;
+ } else {
+ u->mixer_path_set = mapping->input_path_set;
+ }
return;
@@ -1807,10 +1834,9 @@ fail:
u->mixer_path = NULL;
}
- if (u->mixer_handle) {
- snd_mixer_close(u->mixer_handle);
- u->mixer_handle = NULL;
- }
+ u->mixer_handle = NULL;
+ pa_hashmap_free(u->mixers);
+ u->mixers = NULL;
}
static int setup_mixer(struct userdata *u, bool ignore_dB) {
@@ -1822,16 +1848,31 @@ static int setup_mixer(struct userdata *u, bool ignore_dB) {
return 0;
if (u->source->active_port) {
- pa_alsa_port_data *data;
+ if (!u->ucm_context) {
+ pa_alsa_port_data *data;
- /* We have a list of supported paths, so let's activate the
- * one that has been chosen as active */
+ /* We have a list of supported paths, so let's activate the
+ * one that has been chosen as active */
- data = PA_DEVICE_PORT_DATA(u->source->active_port);
- u->mixer_path = data->path;
+ data = PA_DEVICE_PORT_DATA(u->source->active_port);
+ u->mixer_path = data->path;
- pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted);
+ pa_alsa_path_select(data->path, data->setting, u->mixer_handle, u->source->muted);
+ } else {
+ pa_alsa_ucm_port_data *data;
+ /* First activate the port on the UCM side */
+ if (pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0)
+ return -1;
+
+ data = PA_DEVICE_PORT_DATA(u->source->active_port);
+
+ /* Now activate volume controls, if any */
+ if (data->path) {
+ u->mixer_path = data->path;
+ pa_alsa_path_select(u->mixer_path, NULL, u->mixer_handle, u->source->muted);
+ }
+ }
} else {
if (!u->mixer_path && u->mixer_path_set)
@@ -2152,8 +2193,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
/* ALSA might tweak the sample spec, so recalculate the frame size */
frame_size = pa_frame_size(&ss);
- if (!u->ucm_context)
- find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
+ find_mixer(u, mapping, pa_modargs_get_value(ma, "control", NULL), ignore_dB);
pa_source_new_data_init(&data);
data.driver = driver;
@@ -2210,7 +2250,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
}
if (u->ucm_context)
- pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card);
+ pa_alsa_ucm_add_ports(&data.ports, data.proplist, u->ucm_context, false, card, u->pcm_handle, ignore_dB);
else if (u->mixer_path_set)
pa_alsa_add_ports(&data, u->mixer_path_set, card);
@@ -2276,10 +2316,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
if (update_sw_params(u) < 0)
goto fail;
- if (u->ucm_context) {
- if (u->source->active_port && pa_alsa_ucm_set_port(u->ucm_context, u->source->active_port, false) < 0)
- goto fail;
- } else if (setup_mixer(u, ignore_dB) < 0)
+ if (setup_mixer(u, ignore_dB) < 0)
goto fail;
pa_alsa_dump(PA_LOG_DEBUG, u->pcm_handle);
@@ -2368,11 +2405,12 @@ static void userdata_free(struct userdata *u) {
if (u->mixer_fdl)
pa_alsa_fdlist_free(u->mixer_fdl);
- if (u->mixer_path && !u->mixer_path_set)
+ /* Only free the mixer_path if the sink owns it */
+ if (u->mixer_path && !u->mixer_path_set && !u->ucm_context)
pa_alsa_path_free(u->mixer_path);
- if (u->mixer_handle)
- snd_mixer_close(u->mixer_handle);
+ if (u->mixers)
+ pa_hashmap_free(u->mixers);
if (u->smoother)
pa_smoother_free(u->smoother);
diff --git a/src/modules/alsa/alsa-ucm.c b/src/modules/alsa/alsa-ucm.c
index 0a40ca8..a57be6d 100644
--- a/src/modules/alsa/alsa-ucm.c
+++ b/src/modules/alsa/alsa-ucm.c
@@ -81,34 +81,37 @@ static void device_add_hw_mute_jack(pa_alsa_ucm_device *device, pa_alsa_jack *ja
static pa_alsa_ucm_device *verb_find_device(pa_alsa_ucm_verb *verb, const char *device_name);
-struct ucm_port {
- pa_alsa_ucm_config *ucm;
- pa_device_port *core_port;
-
- /* A single port will be associated with multiple devices if it represents
- * a combination of devices. */
- pa_dynarray *devices; /* pa_alsa_ucm_device */
-};
-static void ucm_port_init(struct ucm_port *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port,
- pa_alsa_ucm_device **devices, unsigned n_devices);
-static void ucm_port_free(pa_device_port *port);
-static void ucm_port_update_available(struct ucm_port *port);
+static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port,
+ pa_alsa_ucm_device **devices, unsigned n_devices);
+static void ucm_port_data_free(pa_device_port *port);
+static void ucm_port_update_available(pa_alsa_ucm_port_data *port);
static struct ucm_items item[] = {
{"PlaybackPCM", PA_ALSA_PROP_UCM_SINK},
{"CapturePCM", PA_ALSA_PROP_UCM_SOURCE},
+ {"PlaybackCTL", PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE},
{"PlaybackVolume", PA_ALSA_PROP_UCM_PLAYBACK_VOLUME},
{"PlaybackSwitch", PA_ALSA_PROP_UCM_PLAYBACK_SWITCH},
+ {"PlaybackMixer", PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE},
+ {"PlaybackMixerElem", PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM},
+ {"PlaybackMasterElem", PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM},
+ {"PlaybackMasterType", PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE},
{"PlaybackPriority", PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY},
{"PlaybackRate", PA_ALSA_PROP_UCM_PLAYBACK_RATE},
{"PlaybackChannels", PA_ALSA_PROP_UCM_PLAYBACK_CHANNELS},
+ {"CaptureCTL", PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE},
{"CaptureVolume", PA_ALSA_PROP_UCM_CAPTURE_VOLUME},
{"CaptureSwitch", PA_ALSA_PROP_UCM_CAPTURE_SWITCH},
+ {"CaptureMixer", PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE},
+ {"CaptureMixerElem", PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM},
+ {"CaptureMasterElem", PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM},
+ {"CaptureMasterType", PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE},
{"CapturePriority", PA_ALSA_PROP_UCM_CAPTURE_PRIORITY},
{"CaptureRate", PA_ALSA_PROP_UCM_CAPTURE_RATE},
{"CaptureChannels", PA_ALSA_PROP_UCM_CAPTURE_CHANNELS},
{"TQ", PA_ALSA_PROP_UCM_QOS},
+ {"JackCTL", PA_ALSA_PROP_UCM_JACK_DEVICE},
{"JackControl", PA_ALSA_PROP_UCM_JACK_CONTROL},
{"JackHWMute", PA_ALSA_PROP_UCM_JACK_HW_MUTE},
{NULL, NULL},
@@ -143,29 +146,25 @@ static struct ucm_info dev_info[] = {
{NULL, 0}
};
-/* UCM profile properties - The verb data is store so it can be used to fill
- * the new profiles properties */
-static int ucm_get_property(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr, const char *verb_name) {
- const char *value;
- char *id;
- int i;
-
- for (i = 0; item[i].id; i++) {
- int err;
-
- id = pa_sprintf_malloc("=%s//%s", item[i].id, verb_name);
- err = snd_use_case_get(uc_mgr, id, &value);
- pa_xfree(id);
- if (err < 0)
- continue;
- pa_log_debug("Got %s for verb %s: %s", item[i].id, verb_name, value);
- pa_proplist_sets(verb->proplist, item[i].property, value);
- free((void*)value);
- }
+static char *ucm_verb_value(
+ snd_use_case_mgr_t *uc_mgr,
+ const char *verb_name,
+ const char *id) {
- return 0;
-};
+ const char *value;
+ char *_id = pa_sprintf_malloc("=%s//%s", id, verb_name);
+ int err = snd_use_case_get(uc_mgr, _id, &value);
+ pa_xfree(_id);
+ if (err < 0)
+ return NULL;
+ pa_log_debug("Got %s for verb %s: %s", id, verb_name, value);
+ /* Use the cast here to allow free() call without casting for callers.
+ * The snd_use_case_get() returns mallocated string.
+ * See the Note: in use-case.h for snd_use_case_get().
+ */
+ return (char *)value;
+}
static int ucm_device_exists(pa_idxset *idxset, pa_alsa_ucm_device *dev) {
pa_alsa_ucm_device *d;
@@ -202,6 +201,139 @@ static void ucm_add_devices_to_idxset(
}
}
+/* Split a string into words. Like pa_split_spaces() but handle '' and "". */
+static char *ucm_split_devnames(const char *c, const char **state) {
+ const char *current = *state ? *state : c;
+ char h;
+ size_t l;
+
+ if (!*current || *c == 0)
+ return NULL;
+
+ current += strspn(current, "\n\r \t");
+ h = *current;
+ if (h == '\'' || h =='"') {
+ c = ++current;
+ for (l = 0; *c && *c != h; l++) c++;
+ if (*c != h)
+ return NULL;
+ *state = c + 1;
+ } else {
+ l = strcspn(current, "\n\r \t");
+ *state = current+l;
+ }
+
+ return pa_xstrndup(current, l);
+}
+
+
+static void ucm_volume_free(pa_alsa_ucm_volume *vol) {
+ pa_assert(vol);
+ pa_xfree(vol->mixer_elem);
+ pa_xfree(vol->master_elem);
+ pa_xfree(vol->master_type);
+ pa_xfree(vol);
+}
+
+/* Get the volume identifier */
+static char *ucm_get_mixer_id(
+ pa_alsa_ucm_device *device,
+ const char *mprop,
+ const char *cprop,
+ const char *cid)
+{
+#if SND_LIB_VERSION >= 0x10201 /* alsa-lib-1.2.1+ check */
+ snd_ctl_elem_id_t *ctl;
+ int err;
+#endif
+ const char *value;
+ char *value2;
+ int index;
+
+ /* mixer element as first, if it's found, return it without modifications */
+ value = pa_proplist_gets(device->proplist, mprop);
+ if (value)
+ return pa_xstrdup(value);
+ /* fallback, get the control element identifier */
+ /* and try to do some heuristic to determine the mixer element name */
+ value = pa_proplist_gets(device->proplist, cprop);
+ if (value == NULL)
+ return NULL;
+#if SND_LIB_VERSION >= 0x10201 /* alsa-lib-1.2.1+ check */
+ /* The new parser may return also element index. */
+ snd_ctl_elem_id_alloca(&ctl);
+ err = snd_use_case_parse_ctl_elem_id(ctl, cid, value);
+ if (err < 0)
+ return NULL;
+ value = snd_ctl_elem_id_get_name(ctl);
+ index = snd_ctl_elem_id_get_index(ctl);
+#else
+#warning "Upgrade to alsa-lib 1.2.1!"
+ index = 0;
+#endif
+ if (!(value2 = pa_str_strip_suffix(value, " Playback Volume")))
+ if (!(value2 = pa_str_strip_suffix(value, " Capture Volume")))
+ if (!(value2 = pa_str_strip_suffix(value, " Volume")))
+ value2 = pa_xstrdup(value);
+ if (index > 0) {
+ char *mix = pa_sprintf_malloc("'%s',%d", value2, index);
+ pa_xfree(value2);
+ return mix;
+ }
+ return value2;
+}
+
+/* Get the volume identifier */
+static pa_alsa_ucm_volume *ucm_get_mixer_volume(
+ pa_alsa_ucm_device *device,
+ const char *mprop,
+ const char *cprop,
+ const char *cid,
+ const char *masterid,
+ const char *mastertype)
+{
+ pa_alsa_ucm_volume *vol;
+ char *mixer_elem;
+
+ mixer_elem = ucm_get_mixer_id(device, mprop, cprop, cid);
+ if (mixer_elem == NULL)
+ return NULL;
+ vol = pa_xnew0(pa_alsa_ucm_volume, 1);
+ if (vol == NULL) {
+ pa_xfree(mixer_elem);
+ return NULL;
+ }
+ vol->mixer_elem = mixer_elem;
+ vol->master_elem = pa_xstrdup(pa_proplist_gets(device->proplist, masterid));
+ vol->master_type = pa_xstrdup(pa_proplist_gets(device->proplist, mastertype));
+ return vol;
+}
+
+/* Get the ALSA mixer device for the UCM device */
+static const char *get_mixer_device(pa_alsa_ucm_device *dev, bool is_sink)
+{
+ const char *dev_name;
+
+ if (is_sink) {
+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE);
+ if (!dev_name)
+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE);
+ } else {
+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE);
+ if (!dev_name)
+ dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE);
+ }
+ return dev_name;
+}
+
+/* Get the ALSA mixer device for the UCM jack */
+static const char *get_jack_mixer_device(pa_alsa_ucm_device *dev, bool is_sink) {
+ const char *dev_name = pa_proplist_gets(dev->proplist, PA_ALSA_PROP_UCM_JACK_DEVICE);
+ if (!dev_name)
+ return get_mixer_device(dev, is_sink);
+ return dev_name;
+}
+
/* Create a property list for this ucm device */
static int ucm_get_device_property(
pa_alsa_ucm_device *device,
@@ -216,9 +348,10 @@ static int ucm_get_device_property(
int err;
uint32_t ui;
int n_confdev, n_suppdev;
+ pa_alsa_ucm_volume *vol;
for (i = 0; item[i].id; i++) {
- id = pa_sprintf_malloc("=%s/%s", item[i].id, device_name);
+ id = pa_sprintf_malloc("%s/%s", item[i].id, device_name);
err = snd_use_case_get(uc_mgr, id, &value);
pa_xfree(id);
if (err < 0)
@@ -240,14 +373,8 @@ static int ucm_get_device_property(
/* get pcm */
value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SINK);
- if (!value) { /* take pcm from verb playback default */
- value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_SINK);
- if (value) {
- pa_log_debug("UCM playback device %s fetch pcm from verb default %s", device_name, value);
- pa_proplist_sets(device->proplist, PA_ALSA_PROP_UCM_SINK, value);
- } else
- pa_log("UCM playback device %s fetch pcm failed", device_name);
- }
+ if (!value) /* take pcm from verb playback default */
+ pa_log("UCM playback device %s fetch pcm failed", device_name);
}
value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_CHANNELS);
@@ -260,14 +387,8 @@ static int ucm_get_device_property(
/* get pcm */
value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_SOURCE);
- if (!value) { /* take pcm from verb capture default */
- value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_SOURCE);
- if (value) {
- pa_log_debug("UCM capture device %s fetch pcm from verb default %s", device_name, value);
- pa_proplist_sets(device->proplist, PA_ALSA_PROP_UCM_SOURCE, value);
- } else
- pa_log("UCM capture device %s fetch pcm failed", device_name);
- }
+ if (!value) /* take pcm from verb capture default */
+ pa_log("UCM capture device %s fetch pcm failed", device_name);
}
if (device->playback_channels == 0 && device->capture_channels == 0) {
@@ -280,8 +401,7 @@ static int ucm_get_device_property(
/* get rate and priority of device */
if (device->playback_channels) { /* sink device */
/* get rate */
- if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_RATE)) ||
- (value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_PLAYBACK_RATE))) {
+ if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_PLAYBACK_RATE))) {
if (pa_atou(value, &ui) == 0 && pa_sample_rate_valid(ui)) {
pa_log_debug("UCM playback device %s rate %d", device_name, ui);
device->playback_rate = ui;
@@ -297,12 +417,20 @@ static int ucm_get_device_property(
else
pa_log_debug("UCM playback priority %s for device %s error", value, device_name);
}
+
+ vol = ucm_get_mixer_volume(device,
+ PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM,
+ PA_ALSA_PROP_UCM_PLAYBACK_VOLUME,
+ "PlaybackVolume",
+ PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM,
+ PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE);
+ if (vol)
+ pa_hashmap_put(device->playback_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), vol);
}
if (device->capture_channels) { /* source device */
/* get rate */
- if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_RATE)) ||
- (value = pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_CAPTURE_RATE))) {
+ if ((value = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_CAPTURE_RATE))) {
if (pa_atou(value, &ui) == 0 && pa_sample_rate_valid(ui)) {
pa_log_debug("UCM capture device %s rate %d", device_name, ui);
device->capture_rate = ui;
@@ -318,6 +446,15 @@ static int ucm_get_device_property(
else
pa_log_debug("UCM capture priority %s for device %s error", value, device_name);
}
+
+ vol = ucm_get_mixer_volume(device,
+ PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM,
+ PA_ALSA_PROP_UCM_CAPTURE_VOLUME,
+ "CaptureVolume",
+ PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM,
+ PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE);
+ if (vol)
+ pa_hashmap_put(device->capture_volumes, pa_xstrdup(pa_proplist_gets(verb->proplist, PA_ALSA_PROP_UCM_NAME)), vol);
}
if (PA_UCM_PLAYBACK_PRIORITY_UNSET(device) || PA_UCM_CAPTURE_PRIORITY_UNSET(device)) {
@@ -421,6 +558,11 @@ static int ucm_get_devices(pa_alsa_ucm_verb *verb, snd_use_case_mgr_t *uc_mgr) {
d->hw_mute_jacks = pa_dynarray_new(NULL);
d->available = PA_AVAILABLE_UNKNOWN;
+ d->playback_volumes = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
+ (pa_free_cb_t) ucm_volume_free);
+ d->capture_volumes = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
+ (pa_free_cb_t) ucm_volume_free);
+
PA_LLIST_PREPEND(pa_alsa_ucm_device, verb->devices, d);
}
@@ -576,17 +718,25 @@ int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index) {
const char **verb_list;
int num_verbs, i, err = 0;
- /* is UCM available for this card ? */
- err = snd_card_get_name(card_index, &card_name);
- if (err < 0) {
- pa_log("Card can't get card_name from card_index %d", card_index);
- goto name_fail;
- }
-
+ /* support multiple card instances, address card directly by index */
+ card_name = pa_sprintf_malloc("hw:%i", card_index);
+ if (card_name == NULL)
+ return -ENOMEM;
err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name);
if (err < 0) {
- pa_log_info("UCM not available for card %s", card_name);
- goto ucm_mgr_fail;
+ /* fallback longname: is UCM available for this card ? */
+ pa_xfree(card_name);
+ err = snd_card_get_name(card_index, &card_name);
+ if (err < 0) {
+ pa_log("Card can't get card_name from card_index %d", card_index);
+ goto name_fail;
+ }
+
+ err = snd_use_case_mgr_open(&ucm->ucm_mgr, card_name);
+ if (err < 0) {
+ pa_log_info("UCM not available for card %s", card_name);
+ goto ucm_mgr_fail;
+ }
}
pa_log_info("UCM available for card %s", card_name);
@@ -626,7 +776,7 @@ ucm_verb_fail:
}
ucm_mgr_fail:
- free(card_name);
+ pa_xfree(card_name);
name_fail:
return err;
@@ -636,6 +786,8 @@ int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, cons
pa_alsa_ucm_device *d;
pa_alsa_ucm_modifier *mod;
pa_alsa_ucm_verb *verb;
+ char *value;
+ unsigned ui;
int err = 0;
*p_verb = NULL;
@@ -650,6 +802,11 @@ int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, cons
pa_proplist_sets(verb->proplist, PA_ALSA_PROP_UCM_NAME, pa_strnull(verb_name));
pa_proplist_sets(verb->proplist, PA_ALSA_PROP_UCM_DESCRIPTION, pa_strna(verb_desc));
+ value = ucm_verb_value(uc_mgr, verb_name, "Priority");
+ if (value && !pa_atou(value, &ui))
+ verb->priority = ui > 10000 ? 10000 : ui;
+ free(value);
+
err = ucm_get_devices(verb, uc_mgr);
if (err < 0)
pa_log("No UCM devices for verb %s", verb_name);
@@ -658,9 +815,6 @@ int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, cons
if (err < 0)
pa_log("No UCM modifiers for verb %s", verb_name);
- /* Verb properties */
- ucm_get_property(verb, uc_mgr, verb_name);
-
PA_LLIST_FOREACH(d, verb->devices) {
const char *dev_name = pa_proplist_gets(d->proplist, PA_ALSA_PROP_UCM_NAME);
@@ -693,6 +847,86 @@ static int pa_alsa_ucm_device_cmp(const void *a, const void *b) {
return strcmp(pa_proplist_gets(d1->proplist, PA_ALSA_PROP_UCM_NAME), pa_proplist_gets(d2->proplist, PA_ALSA_PROP_UCM_NAME));
}
+static void set_eld_devices(pa_hashmap *hash)
+{
+ pa_device_port *port;
+ pa_alsa_ucm_port_data *data;
+ pa_alsa_ucm_device *dev;
+ const char *eld_mixer_device_name;
+ void *state;
+ int idx, eld_device;
+
+ PA_HASHMAP_FOREACH(port, hash, state) {
+ data = PA_DEVICE_PORT_DATA(port);
+ eld_mixer_device_name = NULL;
+ eld_device = -1;
+ PA_DYNARRAY_FOREACH(dev, data->devices, idx) {
+ if (dev->eld_device >= 0 && dev->eld_mixer_device_name) {
+ if (eld_device >= 0 && eld_device != dev->eld_device) {
+ pa_log_error("The ELD device is already set!");
+ } else if (eld_mixer_device_name && pa_streq(dev->eld_mixer_device_name, eld_mixer_device_name)) {
+ pa_log_error("The ELD mixer device is already set (%s, %s)!", dev->eld_mixer_device_name, dev->eld_mixer_device_name);
+ } else {
+ eld_mixer_device_name = dev->eld_mixer_device_name;
+ eld_device = dev->eld_device;
+ }
+ }
+ }
+ data->eld_device = eld_device;
+ data->eld_mixer_device_name = pa_xstrdup(eld_mixer_device_name);
+ }
+}
+
+static void probe_volumes(pa_hashmap *hash, bool is_sink, snd_pcm_t *pcm_handle, pa_hashmap *mixers, bool ignore_dB) {
+ pa_device_port *port;
+ pa_alsa_path *path;
+ pa_alsa_ucm_port_data *data;
+ pa_alsa_ucm_device *dev;
+ snd_mixer_t *mixer_handle;
+ const char *profile, *mdev, *mdev2;
+ void *state, *state2;
+ int idx;
+
+ PA_HASHMAP_FOREACH(port, hash, state) {
+ data = PA_DEVICE_PORT_DATA(port);
+
+ mdev = NULL;
+ PA_DYNARRAY_FOREACH(dev, data->devices, idx) {
+ mdev2 = get_mixer_device(dev, is_sink);
+ if (mdev && !pa_streq(mdev, mdev2)) {
+ pa_log_error("Two mixer device names found ('%s', '%s'), using s/w volume", mdev, mdev2);
+ goto fail;
+ }
+ mdev = mdev2;
+ }
+
+ if (!(mixer_handle = pa_alsa_open_mixer_by_name(mixers, mdev, true))) {
+ pa_log_error("Failed to find a working mixer device (%s).", mdev);
+ goto fail;
+ }
+
+ PA_HASHMAP_FOREACH_KV(profile, path, data->paths, state2) {
+ if (pa_alsa_path_probe(path, NULL, mixer_handle, ignore_dB) < 0) {
+ pa_log_warn("Could not probe path: %s, using s/w volume", data->path->name);
+ pa_hashmap_remove(data->paths, profile);
+ } else if (!path->has_volume) {
+ pa_log_warn("Path %s is not a volume control", data->path->name);
+ pa_hashmap_remove(data->paths, profile);
+ } else
+ pa_log_debug("Set up h/w volume using '%s' for %s:%s", path->name, profile, port->name);
+ }
+ }
+
+ return;
+
+fail:
+ /* We could not probe the paths we created. Free them and revert to software volumes. */
+ PA_HASHMAP_FOREACH(port, hash, state) {
+ data = PA_DEVICE_PORT_DATA(port);
+ pa_hashmap_remove_all(data->paths);
+ }
+}
+
static void ucm_add_port_combination(
pa_hashmap *hash,
pa_alsa_ucm_mapping_context *context,
@@ -710,7 +944,11 @@ static void ucm_add_port_combination(
char *name, *desc;
const char *dev_name;
const char *direction;
+ const char *profile;
pa_alsa_ucm_device *sorted[num], *dev;
+ pa_alsa_ucm_port_data *data;
+ pa_alsa_ucm_volume *vol;
+ void *state;
for (i = 0; i < num; i++)
sorted[i] = pdevices[i];
@@ -758,8 +996,6 @@ static void ucm_add_port_combination(
port = pa_hashmap_get(ports, name);
if (!port) {
- struct ucm_port *ucm_port;
-
pa_device_port_new_data port_data;
pa_device_port_new_data_init(&port_data);
@@ -767,15 +1003,45 @@ static void ucm_add_port_combination(
pa_device_port_new_data_set_description(&port_data, desc);
pa_device_port_new_data_set_direction(&port_data, is_sink ? PA_DIRECTION_OUTPUT : PA_DIRECTION_INPUT);
- port = pa_device_port_new(core, &port_data, sizeof(struct ucm_port));
- port->impl_free = ucm_port_free;
+ port = pa_device_port_new(core, &port_data, sizeof(pa_alsa_ucm_port_data));
pa_device_port_new_data_done(&port_data);
- ucm_port = PA_DEVICE_PORT_DATA(port);
- ucm_port_init(ucm_port, context->ucm, port, pdevices, num);
+ data = PA_DEVICE_PORT_DATA(port);
+ ucm_port_data_init(data, context->ucm, port, pdevices, num);
+ port->impl_free = ucm_port_data_free;
pa_hashmap_put(ports, port->name, port);
pa_log_debug("Add port %s: %s", port->name, port->description);
+
+ if (num == 1) {
+ /* To keep things simple and not worry about stacking controls, we only support hardware volumes on non-combination
+ * ports. */
+ data = PA_DEVICE_PORT_DATA(port);
+
+ PA_HASHMAP_FOREACH_KV(profile, vol, is_sink ? dev->playback_volumes : dev->capture_volumes, state) {
+ pa_alsa_path *path = pa_alsa_path_synthesize(vol->mixer_elem,
+ is_sink ? PA_ALSA_DIRECTION_OUTPUT : PA_ALSA_DIRECTION_INPUT);
+
+ if (!path)
+ pa_log_warn("Failed to set up volume control: %s", vol->mixer_elem);
+ else {
+ if (vol->master_elem) {
+ pa_alsa_element *e = pa_alsa_element_get(path, vol->master_elem, false);
+ e->switch_use = PA_ALSA_SWITCH_MUTE;
+ e->volume_use = PA_ALSA_VOLUME_MERGE;
+ }
+
+ pa_hashmap_put(data->paths, pa_xstrdup(profile), path);
+
+ /* Add path also to already created empty path set */
+ dev = sorted[0];
+ if (is_sink)
+ pa_hashmap_put(dev->playback_mapping->output_path_set->paths, pa_xstrdup(vol->mixer_elem), path);
+ else
+ pa_hashmap_put(dev->capture_mapping->input_path_set->paths, pa_xstrdup(vol->mixer_elem), path);
+ }
+ }
+ }
}
port->priority = priority;
@@ -950,6 +1216,9 @@ void pa_alsa_ucm_add_ports_combination(
ucm_add_ports_combination(p, context, is_sink, pdevices, 0, PA_IDXSET_INVALID, ports, cp, core);
pa_xfree(pdevices);
}
+
+ /* ELD devices */
+ set_eld_devices(ports);
}
void pa_alsa_ucm_add_ports(
@@ -957,7 +1226,9 @@ void pa_alsa_ucm_add_ports(
pa_proplist *proplist,
pa_alsa_ucm_mapping_context *context,
bool is_sink,
- pa_card *card) {
+ pa_card *card,
+ snd_pcm_t *pcm_handle,
+ bool ignore_dB) {
uint32_t idx;
char *merged_roles;
@@ -972,6 +1243,9 @@ void pa_alsa_ucm_add_ports(
/* add ports first */
pa_alsa_ucm_add_ports_combination(*p, context, is_sink, card->ports, NULL, card->core);
+ /* now set up volume paths if any */
+ probe_volumes(*p, is_sink, pcm_handle, context->ucm->mixers, ignore_dB);
+
/* then set property PA_PROP_DEVICE_INTENDED_ROLES */
merged_roles = pa_xstrdup(pa_proplist_gets(proplist, PA_PROP_DEVICE_INTENDED_ROLES));
PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
@@ -996,10 +1270,13 @@ void pa_alsa_ucm_add_ports(
}
/* Change UCM verb and device to match selected card profile */
-int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile) {
+int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile) {
int ret = 0;
const char *profile;
pa_alsa_ucm_verb *verb;
+ pa_device_port *port;
+ pa_alsa_ucm_port_data *data;
+ void *state;
if (new_profile == old_profile)
return ret;
@@ -1028,6 +1305,12 @@ int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, co
}
}
+ /* select volume controls on ports */
+ PA_HASHMAP_FOREACH(port, card->ports, state) {
+ data = PA_DEVICE_PORT_DATA(port);
+ data->path = pa_hashmap_get(data->paths, new_profile);
+ }
+
return ret;
}
@@ -1079,23 +1362,35 @@ int pa_alsa_ucm_set_port(pa_alsa_ucm_mapping_context *context, pa_device_port *p
static void ucm_add_mapping(pa_alsa_profile *p, pa_alsa_mapping *m) {
+ pa_alsa_path_set *ps;
+
+ /* create empty path set for the future path additions */
+ ps = pa_xnew0(pa_alsa_path_set, 1);
+ ps->direction = m->direction;
+ ps->paths = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
+
switch (m->direction) {
case PA_ALSA_DIRECTION_ANY:
pa_idxset_put(p->output_mappings, m, NULL);
pa_idxset_put(p->input_mappings, m, NULL);
+ m->output_path_set = ps;
+ m->input_path_set = ps;
break;
case PA_ALSA_DIRECTION_OUTPUT:
pa_idxset_put(p->output_mappings, m, NULL);
+ m->output_path_set = ps;
break;
case PA_ALSA_DIRECTION_INPUT:
pa_idxset_put(p->input_mappings, m, NULL);
+ m->input_path_set = ps;
break;
}
}
static void alsa_mapping_add_ucm_device(pa_alsa_mapping *m, pa_alsa_ucm_device *device) {
char *cur_desc;
- const char *new_desc;
+ const char *new_desc, *mdev;
+ bool is_sink = m->direction == PA_ALSA_DIRECTION_OUTPUT;
pa_idxset_put(m->ucm_context.ucm_devices, device, NULL);
@@ -1111,10 +1406,14 @@ static void alsa_mapping_add_ucm_device(pa_alsa_mapping *m, pa_alsa_ucm_device *
m->description = m->description ? m->description : pa_xstrdup("");
/* save mapping to ucm device */
- if (m->direction == PA_ALSA_DIRECTION_OUTPUT)
+ if (is_sink)
device->playback_mapping = m;
else
device->capture_mapping = m;
+
+ mdev = get_mixer_device(device, is_sink);
+ if (mdev)
+ pa_proplist_sets(m->proplist, "alsa.mixer_device", mdev);
}
static void alsa_mapping_add_ucm_modifier(pa_alsa_mapping *m, pa_alsa_ucm_modifier *modifier) {
@@ -1294,6 +1593,7 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d
pa_alsa_jack *j;
const char *device_name;
const char *jack_control;
+ const char *mixer_device_name;
char *name;
pa_assert(ucm);
@@ -1303,6 +1603,22 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d
jack_control = pa_proplist_gets(device->proplist, PA_ALSA_PROP_UCM_JACK_CONTROL);
if (jack_control) {
+#if SND_LIB_VERSION >= 0x10201
+ snd_ctl_elem_id_t *ctl;
+ int err, index;
+ snd_ctl_elem_id_alloca(&ctl);
+ err = snd_use_case_parse_ctl_elem_id(ctl, "JackControl", jack_control);
+ if (err < 0)
+ return NULL;
+ jack_control = snd_ctl_elem_id_get_name(ctl);
+ index = snd_ctl_elem_id_get_index(ctl);
+ if (index > 0) {
+ pa_log("[%s] Invalid JackControl index value: \"%s\",%d", device_name, jack_control, index);
+ return NULL;
+ }
+#else
+#warning "Upgrade to alsa-lib 1.2.1!"
+#endif
if (!pa_endswith(jack_control, " Jack")) {
pa_log("[%s] Invalid JackControl value: \"%s\"", device_name, jack_control);
return NULL;
@@ -1312,16 +1628,22 @@ static pa_alsa_jack* ucm_get_jack(pa_alsa_ucm_config *ucm, pa_alsa_ucm_device *d
* end, so drop the trailing " Jack". */
name = pa_xstrndup(jack_control, strlen(jack_control) - 5);
} else {
- /* The jack control hasn't been explicitly configured - try a jack name
- * that is the same as the device name. */
- name = pa_xstrdup(device_name);
+ /* The jack control hasn't been explicitly configured, fail. */
+ return NULL;
}
PA_LLIST_FOREACH(j, ucm->jacks)
if (pa_streq(j->name, name))
goto finish;
- j = pa_alsa_jack_new(NULL, name);
+ mixer_device_name = get_jack_mixer_device(device, true);
+ if (!mixer_device_name)
+ mixer_device_name = get_jack_mixer_device(device, false);
+ if (!mixer_device_name) {
+ pa_log("[%s] No mixer device name for JackControl \"%s\"", device_name, jack_control);
+ return NULL;
+ }
+ j = pa_alsa_jack_new(NULL, mixer_device_name, name);
PA_LLIST_PREPEND(pa_alsa_jack, ucm->jacks, j);
finish:
@@ -1342,7 +1664,7 @@ static int ucm_create_profile(
pa_alsa_ucm_modifier *mod;
int i = 0;
const char *name, *sink, *source;
- char *verb_cmp, *c;
+ unsigned int priority;
pa_assert(ps);
@@ -1362,24 +1684,26 @@ static int ucm_create_profile(
p->supported = true;
pa_hashmap_put(ps->profiles, p->name, p);
- /* TODO: get profile priority from ucm info or policy management */
- c = verb_cmp = pa_xstrdup(verb_name);
- while (*c) {
- if (*c == '_') *c = ' ';
- c++;
- }
+ /* TODO: get profile priority from policy management */
+ priority = verb->priority;
- for (i = 0; verb_info[i].id; i++) {
- if (strcasecmp(verb_info[i].id, verb_cmp) == 0) {
- p->priority = verb_info[i].priority;
- break;
+ if (priority == 0) {
+ char *verb_cmp, *c;
+ c = verb_cmp = pa_xstrdup(verb_name);
+ while (*c) {
+ if (*c == '_') *c = ' ';
+ c++;
+ }
+ for (i = 0; verb_info[i].id; i++) {
+ if (strcasecmp(verb_info[i].id, verb_cmp) == 0) {
+ priority = verb_info[i].priority;
+ break;
+ }
}
+ pa_xfree(verb_cmp);
}
- pa_xfree(verb_cmp);
-
- if (verb_info[i].id == NULL)
- p->priority = 1000;
+ p->priority = priority;
PA_LLIST_FOREACH(dev, verb->devices) {
pa_alsa_jack *jack;
@@ -1393,7 +1717,8 @@ static int ucm_create_profile(
ucm_create_mapping(ucm, ps, p, dev, verb_name, name, sink, source);
jack = ucm_get_jack(ucm, dev);
- device_set_jack(dev, jack);
+ if (jack)
+ device_set_jack(dev, jack);
/* JackHWMute contains a list of device names. Each listed device must
* be associated with the jack object that we just created. */
@@ -1402,7 +1727,7 @@ static int ucm_create_profile(
char *hw_mute_device_name;
const char *state = NULL;
- while ((hw_mute_device_name = pa_split_spaces(jack_hw_mute, &state))) {
+ while ((hw_mute_device_name = ucm_split_devnames(jack_hw_mute, &state))) {
pa_alsa_ucm_verb *verb2;
bool device_found = false;
@@ -1446,6 +1771,33 @@ static int ucm_create_profile(
return 0;
}
+static void mapping_init_eld(pa_alsa_mapping *m, snd_pcm_t *pcm)
+{
+ pa_alsa_ucm_mapping_context *context = &m->ucm_context;
+ pa_alsa_ucm_device *dev;
+ uint32_t idx;
+ char *mdev;
+ snd_pcm_info_t *info;
+ int pcm_card, pcm_device;
+
+ snd_pcm_info_alloca(&info);
+ if (snd_pcm_info(pcm, info) < 0)
+ return;
+
+ if ((pcm_card = snd_pcm_info_get_card(info)) < 0)
+ return;
+ if ((pcm_device = snd_pcm_info_get_device(info)) < 0)
+ return;
+
+ PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
+ mdev = pa_sprintf_malloc("hw:%i", pcm_card);
+ if (mdev == NULL)
+ continue;
+ dev->eld_mixer_device_name = mdev;
+ dev->eld_device = pcm_device;
+ }
+}
+
static snd_pcm_t* mapping_open_pcm(pa_alsa_ucm_config *ucm, pa_alsa_mapping *m, int mode) {
snd_pcm_t* pcm;
pa_sample_spec try_ss = ucm->core->default_sample_spec;
@@ -1467,8 +1819,11 @@ static snd_pcm_t* mapping_open_pcm(pa_alsa_ucm_config *ucm, pa_alsa_mapping *m,
pcm = pa_alsa_open_by_device_string(m->device_strings[0], NULL, &try_ss,
&try_map, mode, &try_period_size, &try_buffer_size, 0, NULL, NULL, exact_channels);
- if (pcm && !exact_channels)
- m->channel_map = try_map;
+ if (pcm) {
+ if (!exact_channels)
+ m->channel_map = try_map;
+ mapping_init_eld(m, pcm);
+ }
return pcm;
}
@@ -1500,27 +1855,28 @@ static void profile_finalize_probing(pa_alsa_profile *p) {
}
}
-static void ucm_mapping_jack_probe(pa_alsa_mapping *m) {
- snd_pcm_t *pcm_handle;
+static void ucm_mapping_jack_probe(pa_alsa_mapping *m, pa_hashmap *mixers) {
snd_mixer_t *mixer_handle;
pa_alsa_ucm_mapping_context *context = &m->ucm_context;
pa_alsa_ucm_device *dev;
uint32_t idx;
- pcm_handle = m->direction == PA_ALSA_DIRECTION_OUTPUT ? m->output_pcm : m->input_pcm;
- mixer_handle = pa_alsa_open_mixer_for_pcm(pcm_handle, NULL);
- if (!mixer_handle)
- return;
-
PA_IDXSET_FOREACH(dev, context->ucm_devices, idx) {
bool has_control;
- has_control = pa_alsa_mixer_find(mixer_handle, dev->jack->alsa_name, 0) != NULL;
+ if (!dev->jack || !dev->jack->mixer_device_name)
+ continue;
+
+ mixer_handle = pa_alsa_open_mixer_by_name(mixers, dev->jack->mixer_device_name, true);
+ if (!mixer_handle) {
+ pa_log_error("Unable to determine open mixer device '%s' for jack %s", dev->jack->mixer_device_name, dev->jack->name);
+ continue;
+ }
+
+ has_control = pa_alsa_mixer_find_card(mixer_handle, dev->jack->alsa_name, 0) != NULL;
pa_alsa_jack_set_has_control(dev->jack, has_control);
pa_log_info("UCM jack %s has_control=%d", dev->jack->name, dev->jack->has_control);
}
-
- snd_mixer_close(mixer_handle);
}
static void ucm_probe_profile_set(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *ps) {
@@ -1578,11 +1934,11 @@ static void ucm_probe_profile_set(pa_alsa_ucm_config *ucm, pa_alsa_profile_set *
PA_IDXSET_FOREACH(m, p->output_mappings, idx)
if (!PA_UCM_IS_MODIFIER_MAPPING(m))
- ucm_mapping_jack_probe(m);
+ ucm_mapping_jack_probe(m, ucm->mixers);
PA_IDXSET_FOREACH(m, p->input_mappings, idx)
if (!PA_UCM_IS_MODIFIER_MAPPING(m))
- ucm_mapping_jack_probe(m);
+ ucm_mapping_jack_probe(m, ucm->mixers);
profile_finalize_probing(p);
}
@@ -1636,11 +1992,20 @@ static void free_verb(pa_alsa_ucm_verb *verb) {
if (di->ucm_ports)
pa_dynarray_free(di->ucm_ports);
+ if (di->playback_volumes)
+ pa_hashmap_free(di->playback_volumes);
+ if (di->capture_volumes)
+ pa_hashmap_free(di->capture_volumes);
+
pa_proplist_free(di->proplist);
+
if (di->conflicting_devices)
pa_idxset_free(di->conflicting_devices, NULL);
if (di->supported_devices)
pa_idxset_free(di->supported_devices, NULL);
+
+ pa_xfree(di->eld_mixer_device_name);
+
pa_xfree(di);
}
@@ -1771,7 +2136,7 @@ void pa_alsa_ucm_roled_stream_end(pa_alsa_ucm_config *ucm, const char *role, pa_
}
}
-static void device_add_ucm_port(pa_alsa_ucm_device *device, struct ucm_port *port) {
+static void device_add_ucm_port(pa_alsa_ucm_device *device, pa_alsa_ucm_port_data *port) {
pa_assert(device);
pa_assert(port);
@@ -1799,7 +2164,7 @@ static void device_add_hw_mute_jack(pa_alsa_ucm_device *device, pa_alsa_jack *ja
}
static void device_set_available(pa_alsa_ucm_device *device, pa_available_t available) {
- struct ucm_port *port;
+ pa_alsa_ucm_port_data *port;
unsigned idx;
pa_assert(device);
@@ -1833,8 +2198,8 @@ void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device) {
device_set_available(device, available);
}
-static void ucm_port_init(struct ucm_port *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port,
- pa_alsa_ucm_device **devices, unsigned n_devices) {
+static void ucm_port_data_init(pa_alsa_ucm_port_data *port, pa_alsa_ucm_config *ucm, pa_device_port *core_port,
+ pa_alsa_ucm_device **devices, unsigned n_devices) {
unsigned i;
pa_assert(ucm);
@@ -1844,17 +2209,21 @@ static void ucm_port_init(struct ucm_port *port, pa_alsa_ucm_config *ucm, pa_dev
port->ucm = ucm;
port->core_port = core_port;
port->devices = pa_dynarray_new(NULL);
+ port->eld_device = -1;
for (i = 0; i < n_devices; i++) {
pa_dynarray_append(port->devices, devices[i]);
device_add_ucm_port(devices[i], port);
}
+ port->paths = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree,
+ (pa_free_cb_t) pa_alsa_path_free);
+
ucm_port_update_available(port);
}
-static void ucm_port_free(pa_device_port *port) {
- struct ucm_port *ucm_port;
+static void ucm_port_data_free(pa_device_port *port) {
+ pa_alsa_ucm_port_data *ucm_port;
pa_assert(port);
@@ -1862,9 +2231,14 @@ static void ucm_port_free(pa_device_port *port) {
if (ucm_port->devices)
pa_dynarray_free(ucm_port->devices);
+
+ if (ucm_port->paths)
+ pa_hashmap_free(ucm_port->paths);
+
+ pa_xfree(ucm_port->eld_mixer_device_name);
}
-static void ucm_port_update_available(struct ucm_port *port) {
+static void ucm_port_update_available(pa_alsa_ucm_port_data *port) {
pa_alsa_ucm_device *device;
unsigned idx;
pa_available_t available = PA_AVAILABLE_YES;
@@ -1896,7 +2270,7 @@ pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_cha
return NULL;
}
-int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile) {
+int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile) {
return -1;
}
@@ -1909,7 +2283,9 @@ void pa_alsa_ucm_add_ports(
pa_proplist *proplist,
pa_alsa_ucm_mapping_context *context,
bool is_sink,
- pa_card *card) {
+ pa_card *card,
+ snd_pcm_t *pcm_handle,
+ bool ignore_dB) {
}
void pa_alsa_ucm_add_ports_combination(
diff --git a/src/modules/alsa/alsa-ucm.h b/src/modules/alsa/alsa-ucm.h
index c926f3c..e7a795c 100644
--- a/src/modules/alsa/alsa-ucm.h
+++ b/src/modules/alsa/alsa-ucm.h
@@ -45,12 +45,33 @@ typedef void snd_use_case_mgr_t;
/** For devices: Playback roles */
#define PA_ALSA_PROP_UCM_PLAYBACK_ROLES "alsa.ucm.playback.roles"
+/** For devices: Playback control device name */
+#define PA_ALSA_PROP_UCM_PLAYBACK_CTL_DEVICE "alsa.ucm.playback.ctldev"
+
/** For devices: Playback control volume ID string. e.g PlaybackVolume */
#define PA_ALSA_PROP_UCM_PLAYBACK_VOLUME "alsa.ucm.playback.volume"
/** For devices: Playback switch e.g PlaybackSwitch */
#define PA_ALSA_PROP_UCM_PLAYBACK_SWITCH "alsa.ucm.playback.switch"
+/** For devices: Playback mixer device name */
+#define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_DEVICE "alsa.ucm.playback.mixer.device"
+
+/** For devices: Playback mixer identifier */
+#define PA_ALSA_PROP_UCM_PLAYBACK_MIXER_ELEM "alsa.ucm.playback.mixer.element"
+
+/** For devices: Playback mixer master identifier */
+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ELEM "alsa.ucm.playback.master.element"
+
+/** For devices: Playback mixer master type */
+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type"
+
+/** For devices: Playback mixer master identifier */
+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_ID "alsa.ucm.playback.master.id"
+
+/** For devices: Playback mixer master type */
+#define PA_ALSA_PROP_UCM_PLAYBACK_MASTER_TYPE "alsa.ucm.playback.master.type"
+
/** For devices: Playback priority */
#define PA_ALSA_PROP_UCM_PLAYBACK_PRIORITY "alsa.ucm.playback.priority"
@@ -63,12 +84,33 @@ typedef void snd_use_case_mgr_t;
/** For devices: Capture roles */
#define PA_ALSA_PROP_UCM_CAPTURE_ROLES "alsa.ucm.capture.roles"
+/** For devices: Capture control device name */
+#define PA_ALSA_PROP_UCM_CAPTURE_CTL_DEVICE "alsa.ucm.capture.ctldev"
+
/** For devices: Capture controls volume ID string. e.g CaptureVolume */
#define PA_ALSA_PROP_UCM_CAPTURE_VOLUME "alsa.ucm.capture.volume"
/** For devices: Capture switch e.g CaptureSwitch */
#define PA_ALSA_PROP_UCM_CAPTURE_SWITCH "alsa.ucm.capture.switch"
+/** For devices: Capture mixer device name */
+#define PA_ALSA_PROP_UCM_CAPTURE_MIXER_DEVICE "alsa.ucm.capture.mixer.device"
+
+/** For devices: Capture mixer identifier */
+#define PA_ALSA_PROP_UCM_CAPTURE_MIXER_ELEM "alsa.ucm.capture.mixer.element"
+
+/** For devices: Capture mixer identifier */
+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ELEM "alsa.ucm.capture.master.element"
+
+/** For devices: Capture mixer identifier */
+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type"
+
+/** For devices: Capture mixer identifier */
+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_ID "alsa.ucm.capture.master.id"
+
+/** For devices: Capture mixer identifier */
+#define PA_ALSA_PROP_UCM_CAPTURE_MASTER_TYPE "alsa.ucm.capture.master.type"
+
/** For devices: Capture priority */
#define PA_ALSA_PROP_UCM_CAPTURE_PRIORITY "alsa.ucm.capture.priority"
@@ -84,6 +126,9 @@ typedef void snd_use_case_mgr_t;
/** For devices: The modifier (if any) that this device corresponds to */
#define PA_ALSA_PROP_UCM_MODIFIER "alsa.ucm.modifier"
+/* Corresponds to the "JackCTL" UCM value. */
+#define PA_ALSA_PROP_UCM_JACK_DEVICE "alsa.ucm.jack_device"
+
/* Corresponds to the "JackControl" UCM value. */
#define PA_ALSA_PROP_UCM_JACK_CONTROL "alsa.ucm.jack_control"
@@ -95,10 +140,12 @@ typedef struct pa_alsa_ucm_modifier pa_alsa_ucm_modifier;
typedef struct pa_alsa_ucm_device pa_alsa_ucm_device;
typedef struct pa_alsa_ucm_config pa_alsa_ucm_config;
typedef struct pa_alsa_ucm_mapping_context pa_alsa_ucm_mapping_context;
+typedef struct pa_alsa_ucm_port_data pa_alsa_ucm_port_data;
+typedef struct pa_alsa_ucm_volume pa_alsa_ucm_volume;
int pa_alsa_ucm_query_profiles(pa_alsa_ucm_config *ucm, int card_index);
pa_alsa_profile_set* pa_alsa_ucm_add_profile_set(pa_alsa_ucm_config *ucm, pa_channel_map *default_channel_map);
-int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, const char *new_profile, const char *old_profile);
+int pa_alsa_ucm_set_profile(pa_alsa_ucm_config *ucm, pa_card *card, const char *new_profile, const char *old_profile);
int pa_alsa_ucm_get_verb(snd_use_case_mgr_t *uc_mgr, const char *verb_name, const char *verb_desc, pa_alsa_ucm_verb **p_verb);
@@ -107,7 +154,9 @@ void pa_alsa_ucm_add_ports(
pa_proplist *proplist,
pa_alsa_ucm_mapping_context *context,
bool is_sink,
- pa_card *card);
+ pa_card *card,
+ snd_pcm_t *pcm_handle,
+ bool ignore_dB);
void pa_alsa_ucm_add_ports_combination(
pa_hashmap *hash,
pa_alsa_ucm_mapping_context *context,
@@ -139,6 +188,11 @@ struct pa_alsa_ucm_device {
unsigned playback_channels;
unsigned capture_channels;
+ /* These may be different per verb, so we store this as a hashmap of verb -> volume_control. We might eventually want to
+ * make this a hashmap of verb -> per-verb-device-properties-struct. */
+ pa_hashmap *playback_volumes;
+ pa_hashmap *capture_volumes;
+
pa_alsa_mapping *playback_mapping;
pa_alsa_mapping *capture_mapping;
@@ -153,6 +207,9 @@ struct pa_alsa_ucm_device {
pa_alsa_jack *jack;
pa_dynarray *hw_mute_jacks; /* pa_alsa_jack */
pa_available_t available;
+
+ char *eld_mixer_device_name;
+ int eld_device;
};
void pa_alsa_ucm_device_update_available(pa_alsa_ucm_device *device);
@@ -184,6 +241,7 @@ struct pa_alsa_ucm_verb {
PA_LLIST_FIELDS(pa_alsa_ucm_verb);
pa_proplist *proplist;
+ unsigned priority;
PA_LLIST_HEAD(pa_alsa_ucm_device, devices);
PA_LLIST_HEAD(pa_alsa_ucm_modifier, modifiers);
@@ -194,6 +252,7 @@ struct pa_alsa_ucm_config {
snd_use_case_mgr_t *ucm_mgr;
pa_alsa_ucm_verb *active_verb;
+ pa_hashmap *mixers;
PA_LLIST_HEAD(pa_alsa_ucm_verb, verbs);
PA_LLIST_HEAD(pa_alsa_jack, jacks);
};
@@ -206,4 +265,28 @@ struct pa_alsa_ucm_mapping_context {
pa_idxset *ucm_modifiers;
};
+struct pa_alsa_ucm_port_data {
+ pa_alsa_ucm_config *ucm;
+ pa_device_port *core_port;
+
+ /* A single port will be associated with multiple devices if it represents
+ * a combination of devices. */
+ pa_dynarray *devices; /* pa_alsa_ucm_device */
+
+ /* profile name -> pa_alsa_path for volume control */
+ pa_hashmap *paths;
+ /* Current path, set when activating profile */
+ pa_alsa_path *path;
+
+ /* ELD info */
+ char *eld_mixer_device_name;
+ int eld_device; /* PCM device number */
+};
+
+struct pa_alsa_ucm_volume {
+ char *mixer_elem; /* mixer element identifier */
+ char *master_elem; /* master mixer element identifier */
+ char *master_type;
+};
+
#endif
diff --git a/src/modules/alsa/alsa-util.c b/src/modules/alsa/alsa-util.c
index bd0a47e..d86f43c 100644
--- a/src/modules/alsa/alsa-util.c
+++ b/src/modules/alsa/alsa-util.c
@@ -1066,6 +1066,7 @@ void pa_alsa_init_proplist_ctl(pa_proplist *p, const char *name) {
int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
snd_pcm_state_t state;
+ snd_pcm_hw_params_t *hwparams;
int err;
pa_assert(pcm);
@@ -1103,16 +1104,25 @@ int pa_alsa_recover_from_poll(snd_pcm_t *pcm, int revents) {
break;
case SND_PCM_STATE_SUSPENDED:
- /* Retry resume 3 times before giving up, then fallback to restarting the stream. */
- for (int i = 0; i < 3; i++) {
- if ((err = snd_pcm_resume(pcm)) == 0)
- return 0;
- if (err != -EAGAIN)
- break;
- pa_msleep(25);
+ snd_pcm_hw_params_alloca(&hwparams);
+
+ if ((err = snd_pcm_hw_params_any(pcm, hwparams)) < 0) {
+ pa_log_debug("snd_pcm_hw_params_any() failed: %s", pa_alsa_strerror(err));
+ return -1;
}
- pa_log_warn("Could not recover alsa device from SUSPENDED state, trying to restart PCM");
- /* Fall through */
+
+ if (snd_pcm_hw_params_can_resume(hwparams)) {
+ /* Retry resume 3 times before giving up, then fallback to restarting the stream. */
+ for (int i = 0; i < 3; i++) {
+ if ((err = snd_pcm_resume(pcm)) == 0)
+ return 0;
+ if (err != -EAGAIN)
+ break;
+ pa_msleep(25);
+ }
+ pa_log_warn("Could not recover alsa device from SUSPENDED state, trying to restart PCM");
+ }
+ /* Fall through */
default:
@@ -1600,7 +1610,11 @@ bool pa_alsa_may_tsched(bool want) {
#define SND_MIXER_ELEM_PULSEAUDIO (SND_MIXER_ELEM_LAST + 10)
-snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device) {
+static snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer,
+ snd_ctl_elem_iface_t iface,
+ const char *name,
+ unsigned int index,
+ unsigned int device) {
snd_mixer_elem_t *elem;
for (elem = snd_mixer_first_elem(mixer); elem; elem = snd_mixer_elem_next(elem)) {
@@ -1608,8 +1622,12 @@ snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsig
if (snd_mixer_elem_get_type(elem) != SND_MIXER_ELEM_PULSEAUDIO)
continue;
helem = snd_mixer_elem_get_private(elem);
+ if (snd_hctl_elem_get_interface(helem) != iface)
+ continue;
if (!pa_streq(snd_hctl_elem_get_name(helem), name))
continue;
+ if (snd_hctl_elem_get_index(helem) != index)
+ continue;
if (snd_hctl_elem_get_device(helem) != device)
continue;
return elem;
@@ -1617,6 +1635,14 @@ snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsig
return NULL;
}
+snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device) {
+ return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_CARD, name, 0, device);
+}
+
+snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device) {
+ return pa_alsa_mixer_find(mixer, SND_CTL_ELEM_IFACE_PCM, name, 0, device);
+}
+
static int mixer_class_compare(const snd_mixer_elem_t *c1, const snd_mixer_elem_t *c2)
{
/* Dummy compare function */
@@ -1700,85 +1726,119 @@ static int prepare_mixer(snd_mixer_t *mixer, const char *dev) {
return 0;
}
-snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device) {
+snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool probe) {
+ char *md = pa_sprintf_malloc("hw:%i", alsa_card_index);
+ snd_mixer_t *m = pa_alsa_open_mixer_by_name(mixers, md, probe);
+ pa_xfree(md);
+ return m;
+}
+
+snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, bool probe) {
int err;
snd_mixer_t *m;
- char *md;
- snd_pcm_info_t* info;
- snd_pcm_info_alloca(&info);
+ pa_alsa_mixer *pm;
+ char *dev2;
+ void *state;
+
+ pa_assert(mixers);
+ pa_assert(dev);
+
+ pm = pa_hashmap_get(mixers, dev);
+
+ /* The quick card number/index lookup (hw:#)
+ * We already know the card number/index, thus use the mixer
+ * from the cache at first.
+ */
+ if (!pm && pa_strneq(dev, "hw:", 3)) {
+ const char *s = dev + 3;
+ int card_index;
+ while (*s && *s >= 0 && *s <= '9') s++;
+ if (*s == '\0' && pa_atoi(dev + 3, &card_index) >= 0) {
+ PA_HASHMAP_FOREACH_KV(dev2, pm, mixers, state) {
+ if (pm->card_index == card_index) {
+ dev = dev2;
+ pm = pa_hashmap_get(mixers, dev);
+ break;
+ }
+ }
+ }
+ }
+
+ if (pm) {
+ if (!probe)
+ pm->used_for_probe_only = false;
+ return pm->mixer_handle;
+ }
if ((err = snd_mixer_open(&m, 0)) < 0) {
pa_log("Error opening mixer: %s", pa_alsa_strerror(err));
return NULL;
}
- /* Then, try by card index */
- md = pa_sprintf_malloc("hw:%i", alsa_card_index);
- if (prepare_mixer(m, md) >= 0) {
-
- if (ctl_device)
- *ctl_device = md;
- else
- pa_xfree(md);
-
- return m;
+ if (prepare_mixer(m, dev) >= 0) {
+ pm = pa_xnew0(pa_alsa_mixer, 1);
+ if (pm) {
+ snd_hctl_t *hctl;
+ pm->card_index = -1;
+ /* determine the ALSA card number (index) and store it to card_index */
+ err = snd_mixer_get_hctl(m, dev, &hctl);
+ if (err >= 0) {
+ snd_ctl_card_info_t *info;
+ snd_ctl_card_info_alloca(&info);
+ err = snd_ctl_card_info(snd_hctl_ctl(hctl), info);
+ if (err >= 0)
+ pm->card_index = snd_ctl_card_info_get_card(info);
+ }
+ pm->used_for_probe_only = probe;
+ pm->mixer_handle = m;
+ pa_hashmap_put(mixers, pa_xstrdup(dev), pm);
+ return m;
+ }
}
- pa_xfree(md);
-
snd_mixer_close(m);
return NULL;
}
-snd_mixer_t *pa_alsa_open_mixer_for_pcm(snd_pcm_t *pcm, char **ctl_device) {
- int err;
- snd_mixer_t *m;
- const char *dev;
+snd_mixer_t *pa_alsa_open_mixer_for_pcm(pa_hashmap *mixers, snd_pcm_t *pcm, bool probe) {
snd_pcm_info_t* info;
snd_pcm_info_alloca(&info);
pa_assert(pcm);
- if ((err = snd_mixer_open(&m, 0)) < 0) {
- pa_log("Error opening mixer: %s", pa_alsa_strerror(err));
- return NULL;
- }
-
- /* First, try by name */
- if ((dev = snd_pcm_name(pcm)))
- if (prepare_mixer(m, dev) >= 0) {
- if (ctl_device)
- *ctl_device = pa_xstrdup(dev);
-
- return m;
- }
-
- /* Then, try by card index */
if (snd_pcm_info(pcm, info) >= 0) {
- char *md;
int card_idx;
- if ((card_idx = snd_pcm_info_get_card(info)) >= 0) {
-
- md = pa_sprintf_malloc("hw:%i", card_idx);
-
- if (!dev || !pa_streq(dev, md))
- if (prepare_mixer(m, md) >= 0) {
+ if ((card_idx = snd_pcm_info_get_card(info)) >= 0)
+ return pa_alsa_open_mixer(mixers, card_idx, probe);
+ }
- if (ctl_device)
- *ctl_device = md;
- else
- pa_xfree(md);
+ return NULL;
+}
- return m;
- }
+void pa_alsa_mixer_set_fdlist(pa_hashmap *mixers, snd_mixer_t *mixer_handle, pa_mainloop_api *ml)
+{
+ pa_alsa_mixer *pm;
+ void *state;
- pa_xfree(md);
+ PA_HASHMAP_FOREACH(pm, mixers, state)
+ if (pm->mixer_handle == mixer_handle) {
+ pm->used_for_probe_only = false;
+ if (!pm->fdl) {
+ pm->fdl = pa_alsa_fdlist_new();
+ if (pm->fdl)
+ pa_alsa_fdlist_set_handle(pm->fdl, pm->mixer_handle, NULL, ml);
+ }
}
- }
+}
- snd_mixer_close(m);
- return NULL;
+void pa_alsa_mixer_free(pa_alsa_mixer *mixer)
+{
+ if (mixer->fdl)
+ pa_alsa_fdlist_free(mixer->fdl);
+ if (mixer->mixer_handle)
+ snd_mixer_close(mixer->mixer_handle);
+ pa_xfree(mixer);
}
int pa_alsa_get_hdmi_eld(snd_hctl_elem_t *elem, pa_hdmi_eld *eld) {
diff --git a/src/modules/alsa/alsa-util.h b/src/modules/alsa/alsa-util.h
index 4ceaa06..0d3d5af 100644
--- a/src/modules/alsa/alsa-util.h
+++ b/src/modules/alsa/alsa-util.h
@@ -141,9 +141,14 @@ const char* pa_alsa_strerror(int errnum);
bool pa_alsa_may_tsched(bool want);
-snd_mixer_elem_t *pa_alsa_mixer_find(snd_mixer_t *mixer, const char *name, unsigned int device);
-
-snd_mixer_t *pa_alsa_open_mixer(int alsa_card_index, char **ctl_device);
+snd_mixer_elem_t *pa_alsa_mixer_find_card(snd_mixer_t *mixer, const char *name, unsigned int device);
+snd_mixer_elem_t *pa_alsa_mixer_find_pcm(snd_mixer_t *mixer, const char *name, unsigned int device);
+
+snd_mixer_t *pa_alsa_open_mixer(pa_hashmap *mixers, int alsa_card_index, bool probe);
+snd_mixer_t *pa_alsa_open_mixer_by_name(pa_hashmap *mixers, const char *dev, bool probe);
+snd_mixer_t *pa_alsa_open_mixer_for_pcm(pa_hashmap *mixers, snd_pcm_t *pcm, bool probe);
+void pa_alsa_mixer_set_fdlist(pa_hashmap *mixers, snd_mixer_t *mixer, pa_mainloop_api *ml);
+void pa_alsa_mixer_free(pa_alsa_mixer *mixer);
typedef struct pa_hdmi_eld pa_hdmi_eld;
struct pa_hdmi_eld {
diff --git a/src/modules/alsa/meson.build b/src/modules/alsa/meson.build
index 5309dc1..f31eeb5 100644
--- a/src/modules/alsa/meson.build
+++ b/src/modules/alsa/meson.build
@@ -32,7 +32,7 @@ libalsa_util = shared_library('alsa-util',
c_args : [pa_c_args, server_c_args],
link_args : [nodelete_link_args],
include_directories : [configinc, topinc],
- dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, alsa_dep, dbus_dep, libatomic_ops_dep, libm_dep, udev_dep],
+ dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, alsa_dep, dbus_dep, libatomic_ops_dep, libm_dep, udev_dep, libintl_dep],
install : true,
install_rpath : privlibdir,
install_dir : modlibexecdir,
diff --git a/src/modules/alsa/mixer/paths/analog-output-speaker.conf b/src/modules/alsa/mixer/paths/analog-output-speaker.conf
index 9f4dac4..6f9968e 100644
--- a/src/modules/alsa/mixer/paths/analog-output-speaker.conf
+++ b/src/modules/alsa/mixer/paths/analog-output-speaker.conf
@@ -56,6 +56,9 @@ state.unplugged = unknown
state.plugged = no
state.unplugged = unknown
+[Jack Speaker]
+required-any = any
+
[Jack Speaker Phantom]
required-any = any
state.plugged = unknown
diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common
index e52830d..7bf3463 100644
--- a/src/modules/alsa/mixer/paths/analog-output.conf.common
+++ b/src/modules/alsa/mixer/paths/analog-output.conf.common
@@ -85,7 +85,8 @@
; required-any = ignore | enumeration | any # In this element, either this or another option must exist (or an element)
; required-absent = ignore | enumeration | any # In this element, this option must not exist or the path will be invalid
;
-; [Element ...] # For each element that we shall control
+; [Element ...] # For each element that we shall control. The "..." here is the element name,
+; # or name and index separated by a comma.
; required = ignore | switch | volume | enumeration | any # If set, require this element to be of this kind and available,
; # otherwise don't consider this path valid for the card
; required-any = ignore | switch | volume | enumeration | any # If set, at least one of the elements or jacks with required-any in this
diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf b/src/modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf
index 5842bfe..5842bfe 100644
--- a/src/modules/alsa/mixer/paths/steelseries-arctis-5-output-chat.conf
+++ b/src/modules/alsa/mixer/paths/steelseries-arctis-output-chat-common.conf
diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf b/src/modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf
index b758a6f..b758a6f 100644
--- a/src/modules/alsa/mixer/paths/steelseries-arctis-5-output-game.conf
+++ b/src/modules/alsa/mixer/paths/steelseries-arctis-output-game-common.conf
diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-7-input.conf b/src/modules/alsa/mixer/paths/usb-gaming-headset-input.conf
index 3fa36e9..9fa7fe9 100644
--- a/src/modules/alsa/mixer/paths/steelseries-arctis-7-input.conf
+++ b/src/modules/alsa/mixer/paths/usb-gaming-headset-input.conf
@@ -13,8 +13,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
-; Steelseries Arctis 7 USB headset microphone path. Works also with Arctis Pro
-; Wireless.
+; USB gaming headset microphone input path. These headsets usually have two
+; output devices. The first one is mono, meant for voice audio, and the second
+; one is stereo, meant for everything else. The purpose of this unusual design
+; is to provide separate volume controls for voice and other audio, which can
+; be useful in gaming.
+;
+; Works with:
+; Steelseries Arctis 7
+; Steelseries Arctis Pro Wireless.
+; Lucidsound LS31
[General]
description-key = analog-input-microphone-headset
diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf
index d8b24a2..6df662f 100644
--- a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-mono.conf
+++ b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-mono.conf
@@ -13,11 +13,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
-; Steelseries Arctis 7 USB headset mono output path. Works also with Arctis Pro
-; Wireless. The headset has two output devices. The first one is mono, meant
-; for voice audio, and the second one is stereo, meant for everything else. The
-; purpose of this unusual design is to provide separate volume controls for
-; voice and other audio, which can be useful in gaming.
+; USB gaming headset mono output path. These headsets usually have two
+; output devices. The first one is mono, meant for voice audio, and the second
+; one is stereo, meant for everything else. The purpose of this unusual design
+; is to provide separate volume controls for voice and other audio, which can
+; be useful in gaming.
+;
+; Works with:
+; Steelseries Arctis 7
+; Steelseries Arctis Pro Wireless.
+; Lucidsound LS31
[General]
description-key = analog-output-headphones-mono
diff --git a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf
index fcc58a0..e3f91cd 100644
--- a/src/modules/alsa/mixer/paths/steelseries-arctis-7-output-stereo.conf
+++ b/src/modules/alsa/mixer/paths/usb-gaming-headset-output-stereo.conf
@@ -13,11 +13,16 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
-; Steelseries Arctis 7 USB headset stereo output path. Works also with Arctis
-; Pro Wireless. The headset has two output devices. The first one is mono,
-; meant for voice audio, and the second one is stereo, meant for everything
-; else. The purpose of this unusual design is to provide separate volume
-; controls for voice and other audio, which can be useful in gaming.
+; USB gaming headset mono output path. These headsets usually have two
+; output devices. The first one is mono, meant for voice audio, and the second
+; one is stereo, meant for everything else. The purpose of this unusual design
+; is to provide separate volume controls for voice and other audio, which can
+; be useful in gaming.
+;
+; Works with:
+; Steelseries Arctis 7
+; Steelseries Arctis Pro Wireless.
+; Lucidsound LS31
;
; This path doesn't provide hardware volume control, because the stereo
; output is controlled by the PCM element with index 1, and currently
diff --git a/src/modules/alsa/mixer/profile-sets/default.conf b/src/modules/alsa/mixer/profile-sets/default.conf
index 34c51bc..c73bf5c 100644
--- a/src/modules/alsa/mixer/profile-sets/default.conf
+++ b/src/modules/alsa/mixer/profile-sets/default.conf
@@ -49,7 +49,8 @@
; # If multiple are found to be working they will be available as device ports
; paths-output = ...
; element-input = ... # Instead of configuring a full mixer path simply configure a single
-; # mixer element for volume/mute handling
+; # mixer element for volume/mute handling. The value can be an element
+; # name, or name and index separated by a comma.
; element-output = ...
; priority = ...
; direction = any | input | output # Only useful for?
@@ -72,7 +73,8 @@
; [DecibelFix element] # Decibel fixes can be used to work around missing or incorrect dB
; # information from alsa. A decibel fix is a table that maps volume steps
; # to decibel values for one volume element. The "element" part in the
-; # section title is the name of the volume element.
+; # section title is the name of the volume element (or name and index
+; # separated by a comma).
; #
; # NOTE: This feature is meant just as a help for figuring out the correct
; # decibel values. PulseAudio is not the correct place to maintain the
diff --git a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf
index fe353c3..5f11ed1 100644
--- a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-5-usb-audio.conf
+++ b/src/modules/alsa/mixer/profile-sets/steelseries-arctis-common-usb-audio.conf
@@ -6,13 +6,14 @@ description = Chat
device-strings = hw:%f,0,0
channel-map = left,right
paths-input = analog-input-mic
-paths-output = steelseries-arctis-5-output-chat
+paths-output = steelseries-arctis-output-chat-common
+intended-roles = phone
[Mapping analog-game]
description = Game
device-strings = hw:%f,1,0
channel-map = left,right
-paths-output = steelseries-arctis-5-output-game
+paths-output = steelseries-arctis-output-game-common
direction = output
[Profile output:analog-chat+output:analog-game+input:analog-chat]
diff --git a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf b/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf
index e1394dc..f48b44f 100644
--- a/src/modules/alsa/mixer/profile-sets/steelseries-arctis-7-usb-audio.conf
+++ b/src/modules/alsa/mixer/profile-sets/usb-gaming-headset.conf
@@ -13,12 +13,17 @@
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
-; Steelseries Arctis 7 USB and Arctis Pro Wireless USB headset. These headsets
-; have a microphone and two output devices. The first output device is mono,
-; meant for voice audio, and the second one is stereo, meant for everything
-; else. The purpose of this unusual design is to provide separate volume
+; USB gaming headset.
+; These headsets usually have two output devices. The first one is mono,
+; meant for voice audio, and the second one is stereo, meant for everything
+; else. The purpose of this unusual design is to provide separate volume
; controls for voice and other audio, which can be useful in gaming.
;
+; Works with:
+; Steelseries Arctis 7
+; Steelseries Arctis Pro Wireless.
+; Lucidsound LS31
+;
; See default.conf for an explanation on the directives used here.
[General]
@@ -27,13 +32,14 @@ auto-profiles = yes
[Mapping analog-mono]
device-strings = hw:%f,0,0
channel-map = mono
-paths-output = steelseries-arctis-7-output-mono
-paths-input = steelseries-arctis-7-input
+paths-output = usb-gaming-headset-output-mono
+paths-input = usb-gaming-headset-input
+intended-roles = phone
[Mapping analog-stereo]
device-strings = hw:%f,1,0
channel-map = left,right
-paths-output = steelseries-arctis-7-output-stereo
+paths-output = usb-gaming-headset-output-stereo
direction = output
[Profile output:analog-mono+output:analog-stereo+input:analog-mono]
diff --git a/src/modules/alsa/module-alsa-card.c b/src/modules/alsa/module-alsa-card.c
index 1e1090f..c5852b4 100644
--- a/src/modules/alsa/module-alsa-card.c
+++ b/src/modules/alsa/module-alsa-card.c
@@ -111,9 +111,8 @@ struct userdata {
char *device_id;
int alsa_card_index;
- snd_mixer_t *mixer_handle;
+ pa_hashmap *mixers;
pa_hashmap *jacks;
- pa_alsa_fdlist *mixer_fdl;
pa_card *card;
@@ -241,7 +240,7 @@ static int card_set_profile(pa_card *c, pa_card_profile *new_profile) {
/* if UCM is available for this card then update the verb */
if (u->use_ucm) {
- if (pa_alsa_ucm_set_profile(&u->ucm, nd->profile ? nd->profile->name : NULL,
+ if (pa_alsa_ucm_set_profile(&u->ucm, c, nd->profile ? nd->profile->name : NULL,
od->profile ? od->profile->name : NULL) < 0) {
ret = -1;
goto finish;
@@ -294,7 +293,7 @@ static void init_profile(struct userdata *u) {
if (d->profile && u->use_ucm) {
/* Set initial verb */
- if (pa_alsa_ucm_set_profile(ucm, d->profile->name, NULL) < 0) {
+ if (pa_alsa_ucm_set_profile(ucm, u->card, d->profile->name, NULL) < 0) {
pa_log("Failed to set ucm profile %s", d->profile->name);
return;
}
@@ -513,15 +512,24 @@ static int report_jack_state(snd_mixer_elem_t *melem, unsigned int mask) {
return 0;
}
-static pa_device_port* find_port_with_eld_device(pa_hashmap *ports, int device) {
+static pa_device_port* find_port_with_eld_device(struct userdata *u, int device) {
void *state;
pa_device_port *p;
- PA_HASHMAP_FOREACH(p, ports, state) {
- pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(p);
- pa_assert(data->path);
- if (device == data->path->eld_device)
- return p;
+ if (u->use_ucm) {
+ PA_HASHMAP_FOREACH(p, u->card->ports, state) {
+ pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(p);
+ pa_assert(data->eld_mixer_device_name);
+ if (device == data->eld_device)
+ return p;
+ }
+ } else {
+ PA_HASHMAP_FOREACH(p, u->card->ports, state) {
+ pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(p);
+ pa_assert(data->path);
+ if (device == data->path->eld_device)
+ return p;
+ }
}
return NULL;
}
@@ -538,7 +546,7 @@ static int hdmi_eld_changed(snd_mixer_elem_t *melem, unsigned int mask) {
if (mask == SND_CTL_EVENT_MASK_REMOVE)
return 0;
- p = find_port_with_eld_device(u->card->ports, device);
+ p = find_port_with_eld_device(u, device);
if (p == NULL) {
pa_log_error("Invalid device changed in ALSA: %d", device);
return 0;
@@ -566,33 +574,46 @@ static void init_eld_ctls(struct userdata *u) {
void *state;
pa_device_port *port;
- if (!u->mixer_handle)
- return;
-
/* The code in this function expects ports to have a pa_alsa_port_data
* struct as their data, but in UCM mode ports don't have any data. Hence,
* the ELD controls can't currently be used in UCM mode. */
- if (u->use_ucm)
- return;
-
PA_HASHMAP_FOREACH(port, u->card->ports, state) {
- pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port);
+ snd_mixer_t *mixer_handle;
snd_mixer_elem_t* melem;
int device;
- pa_assert(data->path);
- device = data->path->eld_device;
- if (device < 0)
+ if (u->use_ucm) {
+ pa_alsa_ucm_port_data *data = PA_DEVICE_PORT_DATA(port);
+ device = data->eld_device;
+ if (device < 0 || !data->eld_mixer_device_name)
+ continue;
+
+ mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, data->eld_mixer_device_name, true);
+ } else {
+ pa_alsa_port_data *data = PA_DEVICE_PORT_DATA(port);
+
+ pa_assert(data->path);
+
+ device = data->path->eld_device;
+ if (device < 0)
+ continue;
+
+ mixer_handle = pa_alsa_open_mixer(u->mixers, u->alsa_card_index, true);
+ }
+
+ if (!mixer_handle)
continue;
- melem = pa_alsa_mixer_find(u->mixer_handle, "ELD", device);
+ melem = pa_alsa_mixer_find_pcm(mixer_handle, "ELD", device);
if (melem) {
+ pa_alsa_mixer_set_fdlist(u->mixers, mixer_handle, u->core->mainloop);
snd_mixer_elem_set_callback(melem, hdmi_eld_changed);
snd_mixer_elem_set_callback_private(melem, u);
hdmi_eld_changed(melem, 0);
+ pa_log_info("ELD device found for port %s (%d).", port->name, device);
}
else
- pa_log_debug("No ELD device found for port %s.", port->name);
+ pa_log_debug("No ELD device found for port %s (%d).", port->name, device);
}
}
@@ -627,25 +648,31 @@ static void init_jacks(struct userdata *u) {
if (pa_hashmap_size(u->jacks) == 0)
return;
- u->mixer_fdl = pa_alsa_fdlist_new();
-
- u->mixer_handle = pa_alsa_open_mixer(u->alsa_card_index, NULL);
- if (u->mixer_handle && pa_alsa_fdlist_set_handle(u->mixer_fdl, u->mixer_handle, NULL, u->core->mainloop) >= 0) {
- PA_HASHMAP_FOREACH(jack, u->jacks, state) {
- jack->melem = pa_alsa_mixer_find(u->mixer_handle, jack->alsa_name, 0);
- if (!jack->melem) {
- pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name);
- pa_alsa_jack_set_has_control(jack, false);
- continue;
+ PA_HASHMAP_FOREACH(jack, u->jacks, state) {
+ if (!jack->mixer_device_name) {
+ jack->mixer_handle = pa_alsa_open_mixer(u->mixers, u->alsa_card_index, false);
+ if (!jack->mixer_handle) {
+ pa_log("Failed to open mixer for card %d for jack detection", u->alsa_card_index);
+ continue;
+ }
+ } else {
+ jack->mixer_handle = pa_alsa_open_mixer_by_name(u->mixers, jack->mixer_device_name, false);
+ if (!jack->mixer_handle) {
+ pa_log("Failed to open mixer '%s' for jack detection", jack->mixer_device_name);
+ continue;
}
- snd_mixer_elem_set_callback(jack->melem, report_jack_state);
- snd_mixer_elem_set_callback_private(jack->melem, u);
- report_jack_state(jack->melem, 0);
}
-
- } else
- pa_log("Failed to open mixer for jack detection");
-
+ pa_alsa_mixer_set_fdlist(u->mixers, jack->mixer_handle, u->core->mainloop);
+ jack->melem = pa_alsa_mixer_find_card(jack->mixer_handle, jack->alsa_name, 0);
+ if (!jack->melem) {
+ pa_log_warn("Jack '%s' seems to have disappeared.", jack->alsa_name);
+ pa_alsa_jack_set_has_control(jack, false);
+ continue;
+ }
+ snd_mixer_elem_set_callback(jack->melem, report_jack_state);
+ snd_mixer_elem_set_callback_private(jack->melem, u);
+ report_jack_state(jack->melem, 0);
+ }
}
static void set_card_name(pa_card_new_data *data, pa_modargs *ma, const char *device_id) {
@@ -769,6 +796,10 @@ int pa__init(pa_module *m) {
u->use_ucm = true;
u->ucm.core = m->core;
+ u->mixers = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func,
+ pa_xfree, (pa_free_cb_t) pa_alsa_mixer_free);
+ u->ucm.mixers = u->mixers; /* alias */
+
if (!(u->modargs = pa_modargs_new(m->argument, valid_modargs))) {
pa_log("Failed to parse module arguments.");
goto fail;
@@ -849,7 +880,7 @@ int pa__init(pa_module *m) {
u->profile_set->ignore_dB = ignore_dB;
- pa_alsa_profile_set_probe(u->profile_set, u->device_id, &m->core->default_sample_spec, m->core->default_n_fragments, m->core->default_fragment_size_msec);
+ pa_alsa_profile_set_probe(u->profile_set, u->mixers, u->device_id, &m->core->default_sample_spec, m->core->default_n_fragments, m->core->default_fragment_size_msec);
pa_alsa_profile_set_dump(u->profile_set);
pa_card_new_data_init(&data);
@@ -900,7 +931,8 @@ int pa__init(pa_module *m) {
* results in an infinite loop of "fill buffer, handle underrun". To work
* around this issue, the suspend_when_unavailable flag is used to stop
* playback when the HDMI cable is unplugged. */
- if (pa_safe_streq(pa_proplist_gets(data.proplist, "alsa.driver_name"), "snd_hdmi_lpe_audio")) {
+ if (!u->use_ucm &&
+ pa_safe_streq(pa_proplist_gets(data.proplist, "alsa.driver_name"), "snd_hdmi_lpe_audio")) {
pa_device_port *port;
void *state;
@@ -948,6 +980,16 @@ int pa__init(pa_module *m) {
init_profile(u);
init_eld_ctls(u);
+ /* Remove all probe only mixers */
+ if (u->mixers) {
+ const char *devname;
+ pa_alsa_mixer *pm;
+ void *state;
+ PA_HASHMAP_FOREACH_KV(devname, pm, u->mixers, state)
+ if (pm->used_for_probe_only)
+ pa_hashmap_remove_and_free(u->mixers, devname);
+ }
+
if (reserve)
pa_reserve_wrapper_unref(reserve);
@@ -998,10 +1040,8 @@ void pa__done(pa_module*m) {
if (!(u = m->userdata))
goto finish;
- if (u->mixer_fdl)
- pa_alsa_fdlist_free(u->mixer_fdl);
- if (u->mixer_handle)
- snd_mixer_close(u->mixer_handle);
+ if (u->mixers)
+ pa_hashmap_free(u->mixers);
if (u->jacks)
pa_hashmap_free(u->jacks);
diff --git a/src/modules/alsa/module-alsa-sink.c b/src/modules/alsa/module-alsa-sink.c
index 4d4beb3..a90c5e4 100644
--- a/src/modules/alsa/module-alsa-sink.c
+++ b/src/modules/alsa/module-alsa-sink.c
@@ -52,7 +52,7 @@ PA_MODULE_USAGE(
"tsched_buffer_size=<buffer size when using timer based scheduling> "
"tsched_buffer_watermark=<lower fill watermark> "
"ignore_dB=<ignore dB information from the device?> "
- "control=<name of mixer control> "
+ "control=<name of mixer control, or name and index separated by a comma> "
"rewind_safeguard=<number of bytes that cannot be rewound> "
"deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> "
"deferred_volume_safety_margin=<usec adjustment depending on volume direction> "
diff --git a/src/modules/alsa/module-alsa-source.c b/src/modules/alsa/module-alsa-source.c
index 747ba93..d152283 100644
--- a/src/modules/alsa/module-alsa-source.c
+++ b/src/modules/alsa/module-alsa-source.c
@@ -61,7 +61,7 @@ PA_MODULE_USAGE(
"tsched_buffer_size=<buffer size when using timer based scheduling> "
"tsched_buffer_watermark=<upper fill watermark> "
"ignore_dB=<ignore dB information from the device?> "
- "control=<name of mixer control>"
+ "control=<name of mixer control, or name and index separated by a comma>"
"deferred_volume=<Synchronize software and hardware volume changes to avoid momentary jumps?> "
"deferred_volume_safety_margin=<usec adjustment depending on volume direction> "
"deferred_volume_extra_delay=<usec adjustment to HW volume changes> "
diff --git a/src/modules/bluetooth/meson.build b/src/modules/bluetooth/meson.build
index 7b3de6b..9982cba 100644
--- a/src/modules/bluetooth/meson.build
+++ b/src/modules/bluetooth/meson.build
@@ -26,7 +26,7 @@ libbluez5_util = shared_library('bluez5-util',
c_args : [pa_c_args, server_c_args],
link_args : [nodelete_link_args],
include_directories : [configinc, topinc],
- dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, dbus_dep, sbc_dep],
+ dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, dbus_dep, sbc_dep, libintl_dep],
install : true,
install_rpath : privlibdir,
install_dir : modlibexecdir,
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index cff1cd6..9da5d1a 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -395,7 +395,9 @@ static int sco_process_push(struct userdata *u) {
}
if (!found_tstamp) {
- pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!");
+ PA_ONCE_BEGIN {
+ pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!");
+ } PA_ONCE_END;
tstamp = pa_rtclock_now();
}
@@ -548,13 +550,29 @@ static int a2dp_process_push(struct userdata *u) {
a2dp_prepare_decoder_buffer(u);
for (;;) {
+ uint8_t aux[1024];
+ struct iovec iov;
+ struct cmsghdr *cm;
+ struct msghdr m;
bool found_tstamp = false;
pa_usec_t tstamp;
uint8_t *ptr;
ssize_t l;
size_t processed;
- l = pa_read(u->stream_fd, u->decoder_buffer, u->decoder_buffer_size, &u->stream_write_type);
+ pa_zero(m);
+ pa_zero(aux);
+ pa_zero(iov);
+
+ m.msg_iov = &iov;
+ m.msg_iovlen = 1;
+ m.msg_control = aux;
+ m.msg_controllen = sizeof(aux);
+
+ iov.iov_base = u->decoder_buffer;
+ iov.iov_len = u->decoder_buffer_size;
+
+ l = recvmsg(u->stream_fd, &m, 0);
if (l <= 0) {
@@ -574,8 +592,21 @@ static int a2dp_process_push(struct userdata *u) {
pa_assert((size_t) l <= u->decoder_buffer_size);
/* TODO: get timestamp from rtp */
+
+ for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) {
+ if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SO_TIMESTAMP) {
+ struct timeval *tv = (struct timeval*) CMSG_DATA(cm);
+ pa_rtclock_from_wallclock(tv);
+ tstamp = pa_timeval_load(tv);
+ found_tstamp = true;
+ break;
+ }
+ }
+
if (!found_tstamp) {
- /* pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!"); */
+ PA_ONCE_BEGIN {
+ pa_log_warn("Couldn't find SO_TIMESTAMP data in auxiliary recvmsg() data!");
+ } PA_ONCE_END;
tstamp = pa_rtclock_now();
}
diff --git a/src/modules/echo-cancel/meson.build b/src/modules/echo-cancel/meson.build
index 171a414..641cd35 100644
--- a/src/modules/echo-cancel/meson.build
+++ b/src/modules/echo-cancel/meson.build
@@ -14,7 +14,7 @@ libwebrtc_util = shared_library('webrtc-util',
libwebrtc_util_sources,
cpp_args : [pa_c_args, server_c_args],
include_directories : [configinc, topinc],
- dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep, webrtc_dep],
+ dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep, webrtc_dep, libintl_dep],
link_args : [nodelete_link_args, '-Wl,--unresolved-symbols=ignore-in-object-files'],
install : true,
install_rpath : privlibdir,
diff --git a/src/modules/echo-cancel/module-echo-cancel.c b/src/modules/echo-cancel/module-echo-cancel.c
index 3a4c8c9..f239492 100644
--- a/src/modules/echo-cancel/module-echo-cancel.c
+++ b/src/modules/echo-cancel/module-echo-cancel.c
@@ -1466,6 +1466,8 @@ static bool sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) {
/* Called from main context. */
static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
struct userdata *u;
+ uint32_t idx;
+ pa_source_output *output;
pa_source_output_assert_ref(o);
pa_assert_ctl_context();
@@ -1477,6 +1479,12 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
} else
pa_source_set_asyncmsgq(u->source, NULL);
+ /* Propagate asyncmsq change to attached virtual sources */
+ PA_IDXSET_FOREACH(output, u->source->outputs, idx) {
+ if (output->destination_source && output->moving)
+ output->moving(output, u->source);
+ }
+
if (u->source_auto_desc && dest) {
const char *y, *z;
pa_proplist *pl;
diff --git a/src/modules/gsettings/meson.build b/src/modules/gsettings/meson.build
index f39fb65..68a72c3 100644
--- a/src/modules/gsettings/meson.build
+++ b/src/modules/gsettings/meson.build
@@ -29,7 +29,7 @@ install_data('org.freedesktop.pulseaudio.gschema.xml',
install_dir : join_paths(datadir, 'glib-2.0', 'schemas')
)
-meson.add_install_script('post-install.sh', datadir)
+meson.add_install_script('meson_post_install.py', datadir)
# Conversion from GConf to GSettings
diff --git a/src/modules/gsettings/meson_post_install.py b/src/modules/gsettings/meson_post_install.py
new file mode 100644
index 0000000..0ddb70d
--- /dev/null
+++ b/src/modules/gsettings/meson_post_install.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python3
+
+import os
+import subprocess
+import sys
+
+datadir = sys.argv[1]
+
+# Package managers set this so we don't need to run
+if not os.environ.get('DESTDIR'):
+ schemadir = os.path.join(datadir, 'glib-2.0', 'schemas')
+ print('Compiling gsettings schemas...')
+ subprocess.call(['glib-compile-schemas', schemadir])
+
diff --git a/src/modules/gsettings/post-install.sh b/src/modules/gsettings/post-install.sh
deleted file mode 100755
index cec8b93..0000000
--- a/src/modules/gsettings/post-install.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-set -e
-set -u
-
-DATADIR="$1"
-
-# Package managers set this so we don't need to run
-if [ "${DESTDIR:-}" ]; then exit 0; fi
-
-echo "Compiling GSettings schemas..."
-glib-compile-schemas "$DATADIR/glib-2.0/schemas"
diff --git a/src/modules/jack/module-jackdbus-detect.c b/src/modules/jack/module-jackdbus-detect.c
index 6628102..63c4307 100644
--- a/src/modules/jack/module-jackdbus-detect.c
+++ b/src/modules/jack/module-jackdbus-detect.c
@@ -38,6 +38,8 @@ PA_MODULE_LOAD_ONCE(true);
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_USAGE(
"channels=<number of channels> "
+ "source_channels=<number of channels> "
+ "sink_channels=<number of channels> "
"connect=<connect ports?>");
#define JACK_SERVICE_NAME "org.jackaudio.service"
@@ -59,6 +61,8 @@ PA_MODULE_USAGE(
static const char* const valid_modargs[] = {
"channels",
+ "source_channels",
+ "sink_channels",
"connect",
NULL
};
@@ -79,7 +83,7 @@ struct userdata {
bool filter_added, match_added;
bool is_service_started;
bool autoconnect_ports;
- uint32_t channels;
+ uint32_t channels[JACK_SS_COUNT];
/* Using index here protects us from module unloading without us knowing */
int jack_module_index[JACK_SS_COUNT];
};
@@ -104,8 +108,8 @@ static void ensure_ports_started(struct userdata* u) {
if (!u->jack_module_index[i]) {
char* args;
pa_module* m;
- if (u->channels > 0) {
- args = pa_sprintf_malloc("connect=%s channels=%" PRIu32, pa_yes_no(u->autoconnect_ports), u->channels);
+ if (u->channels[i] > 0) {
+ args = pa_sprintf_malloc("connect=%s channels=%" PRIu32, pa_yes_no(u->autoconnect_ports), u->channels[i]);
} else {
args = pa_sprintf_malloc("connect=%s", pa_yes_no(u->autoconnect_ports));
}
@@ -213,6 +217,8 @@ int pa__init(pa_module *m) {
pa_dbus_connection *connection = NULL;
struct userdata *u = NULL;
pa_modargs *ma;
+ uint32_t channels = 0;
+ int i;
pa_assert(m);
@@ -227,17 +233,29 @@ int pa__init(pa_module *m) {
u->core = m->core;
u->module = m;
u->autoconnect_ports = true;
- u->channels = 0;
if (pa_modargs_get_value_boolean(ma, "connect", &u->autoconnect_ports) < 0) {
pa_log("Failed to parse connect= argument.");
goto fail;
}
- if (pa_modargs_get_value_u32(ma, "channels", &u->channels) < 0 || !pa_channels_valid(u->channels)) {
+ if (pa_modargs_get_value_u32(ma, "channels", &channels) < 0 || (channels > 0 && !pa_channels_valid(channels))) {
pa_log("Failed to parse channels= argument.");
goto fail;
}
+ for (i = 0; i < JACK_SS_COUNT; i++) {
+ u->channels[i] = channels;
+ }
+
+ if (pa_modargs_get_value_u32(ma, "source_channels", &u->channels[JACK_SS_SOURCE]) < 0 || (u->channels[JACK_SS_SOURCE] > 0 && !pa_channels_valid(u->channels[JACK_SS_SOURCE]))) {
+ pa_log("Failed to parse source_channels= argument.");
+ goto fail;
+ }
+
+ if (pa_modargs_get_value_u32(ma, "sink_channels", &u->channels[JACK_SS_SINK]) < 0 || (u->channels[JACK_SS_SINK] > 0 && !pa_channels_valid(u->channels[JACK_SS_SINK]))) {
+ pa_log("Failed to parse sink_channels= argument.");
+ goto fail;
+ }
if (!(connection = pa_dbus_bus_get(m->core, DBUS_BUS_SESSION, &error)) || dbus_error_is_set(&error)) {
diff --git a/src/modules/meson.build b/src/modules/meson.build
index 92d5871..5f04371 100644
--- a/src/modules/meson.build
+++ b/src/modules/meson.build
@@ -55,7 +55,7 @@ all_modules = [
[ 'module-suspend-on-idle', 'module-suspend-on-idle.c' ],
[ 'module-switch-on-connect', 'module-switch-on-connect.c' ],
[ 'module-switch-on-port-available', 'module-switch-on-port-available.c' ],
- [ 'module-tunnel-sink', 'module-tunnel.c', [], [], [x11_dep] ],
+ [ 'module-tunnel-sink', 'module-tunnel.c', [], ['-DTUNNEL_SINK=1'], [x11_dep] ],
[ 'module-tunnel-sink-new', 'module-tunnel-sink-new.c' ],
[ 'module-tunnel-source', 'module-tunnel.c', [], [], [x11_dep] ],
[ 'module-tunnel-source-new', 'module-tunnel-source-new.c' ],
@@ -284,7 +284,7 @@ foreach m : all_modules
install : true,
install_rpath : rpath_dirs,
install_dir : modlibexecdir,
- dependencies : [thread_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep] + extra_deps,
+ dependencies : [thread_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libintl_dep] + extra_deps,
link_args : [nodelete_link_args, '-Wl,--no-undefined' ],
link_with : extra_libs,
name_prefix : '',
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index 25598f7..6aeef49 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -55,7 +55,8 @@ PA_MODULE_USAGE(
#define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
static const char* const valid_modargs[] = {
- "restore_bluetooth_profile=<boolean>"
+ "restore_bluetooth_profile",
+ NULL
};
struct userdata {
diff --git a/src/modules/module-device-manager.c b/src/modules/module-device-manager.c
index 15fdaaa..308ef0b 100644
--- a/src/modules/module-device-manager.c
+++ b/src/modules/module-device-manager.c
@@ -656,14 +656,14 @@ static void route_sink_input(struct userdata *u, pa_sink_input *si) {
pa_assert(u);
pa_assert(u->do_routing);
- /* Don't override user or application routing requests. */
- if (si->save_sink || si->sink_requested_by_application)
- return;
-
/* Skip this if it is already in the process of being moved anyway */
if (!si->sink)
return;
+ /* Don't override user or application routing requests. */
+ if (pa_safe_streq(si->sink->name, si->preferred_sink) || si->sink_requested_by_application)
+ return;
+
auto_filtered_prop = pa_proplist_gets(si->proplist, "module-device-manager.auto_filtered");
if (auto_filtered_prop)
auto_filtered = (pa_parse_boolean(auto_filtered_prop) == 1);
@@ -728,10 +728,6 @@ static void route_source_output(struct userdata *u, pa_source_output *so) {
pa_assert(u);
pa_assert(u->do_routing);
- /* Don't override user or application routing requests. */
- if (so->save_source || so->source_requested_by_application)
- return;
-
if (so->direct_on_input)
return;
@@ -739,6 +735,10 @@ static void route_source_output(struct userdata *u, pa_source_output *so) {
if (!so->source)
return;
+ /* Don't override user or application routing requests. */
+ if (pa_safe_streq(so->source->name, so->preferred_source) || so->source_requested_by_application)
+ return;
+
auto_filtered_prop = pa_proplist_gets(so->proplist, "module-device-manager.auto_filtered");
if (auto_filtered_prop)
auto_filtered = (pa_parse_boolean(auto_filtered_prop) == 1);
@@ -1596,7 +1596,7 @@ int pa__init(pa_module*m) {
}
if (on_rescue) {
- /* A little bit later than module-stream-restore, a little bit earlier than module-intended-roles, module-rescue-streams, ... */
+ /* A little bit later than module-stream-restore, a little bit earlier than module-intended-roles, ... */
u->sink_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE+5, (pa_hook_cb_t) sink_unlink_hook_callback, u);
u->source_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE+5, (pa_hook_cb_t) source_unlink_hook_callback, u);
}
diff --git a/src/modules/module-filter-apply.c b/src/modules/module-filter-apply.c
index faeedcb..c9f3f39 100644
--- a/src/modules/module-filter-apply.c
+++ b/src/modules/module-filter-apply.c
@@ -687,8 +687,7 @@ static pa_hook_result_t sink_unlink_cb(pa_core *core, pa_sink *sink, struct user
uint32_t idx;
/* Attempt to rescue any streams to the parent sink as this is likely
- * the best course of action (as opposed to a generic rescue via
- * module-rescue-streams */
+ * the best course of action */
if (filter->sink == sink) {
pa_sink_input *i;
@@ -769,8 +768,7 @@ static pa_hook_result_t source_unlink_cb(pa_core *core, pa_source *source, struc
uint32_t idx;
/* Attempt to rescue any streams to the parent source as this is likely
- * the best course of action (as opposed to a generic rescue via
- * module-rescue-streams */
+ * the best course of action */
if (filter->source == source) {
pa_source_output *o;
diff --git a/src/modules/module-intended-roles.c b/src/modules/module-intended-roles.c
index adee51c..2269c0d 100644
--- a/src/modules/module-intended-roles.c
+++ b/src/modules/module-intended-roles.c
@@ -175,14 +175,14 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct
if (si->sink == sink)
continue;
- if (si->save_sink)
- continue;
-
/* Skip this if it is already in the process of being moved
* anyway */
if (!si->sink)
continue;
+ if (pa_safe_streq(si->sink->name, si->preferred_sink))
+ continue;
+
/* It might happen that a stream and a sink are set up at the
same time, in which case we want to make sure we don't
interfere with that */
@@ -222,9 +222,6 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (so->source == source)
continue;
- if (so->save_source)
- continue;
-
if (so->direct_on_input)
continue;
@@ -233,6 +230,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (!so->source)
continue;
+ if (pa_safe_streq(so->source->name, so->preferred_source))
+ continue;
+
/* It might happen that a stream and a source are set up at the
same time, in which case we want to make sure we don't
interfere with that */
@@ -398,7 +398,7 @@ int pa__init(pa_module*m) {
}
if (on_rescue) {
- /* A little bit later than module-stream-restore, a little bit earlier than module-rescue-streams, ... */
+ /* A little bit later than module-stream-restore, ... */
u->sink_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE+10, (pa_hook_cb_t) sink_unlink_hook_callback, u);
u->source_unlink_hook_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE+10, (pa_hook_cb_t) source_unlink_hook_callback, u);
}
diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c
index ac57882..336676b 100644
--- a/src/modules/module-null-sink.c
+++ b/src/modules/module-null-sink.c
@@ -360,7 +360,7 @@ int pa__init(pa_module*m) {
goto fail;
}
- u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY|PA_SINK_DYNAMIC_LATENCY);
+ u->sink = pa_sink_new(m->core, &data, PA_SINK_LATENCY | PA_SINK_DYNAMIC_LATENCY | PA_SINK_SET_FORMATS);
pa_sink_new_data_done(&data);
if (!u->sink) {
diff --git a/src/modules/module-remap-source.c b/src/modules/module-remap-source.c
index cad04af..281f413 100644
--- a/src/modules/module-remap-source.c
+++ b/src/modules/module-remap-source.c
@@ -252,6 +252,8 @@ static void source_output_state_change_cb(pa_source_output *o, pa_source_output_
/* Called from main thread */
static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
struct userdata *u;
+ uint32_t idx;
+ pa_source_output *output;
pa_source_output_assert_ref(o);
pa_assert_ctl_context();
@@ -263,6 +265,12 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
} else
pa_source_set_asyncmsgq(u->source, NULL);
+ /* Propagate asyncmsq change to attached virtual sources */
+ PA_IDXSET_FOREACH(output, u->source->outputs, idx) {
+ if (output->destination_source && output->moving)
+ output->moving(output, u->source);
+ }
+
if (u->auto_desc && dest) {
const char *k;
pa_proplist *pl;
diff --git a/src/modules/module-rescue-streams.c b/src/modules/module-rescue-streams.c
index 0d8b1be..ac95896 100644
--- a/src/modules/module-rescue-streams.c
+++ b/src/modules/module-rescue-streams.c
@@ -24,332 +24,23 @@
#include <pulse/xmalloc.h>
#include <pulsecore/core.h>
-#include <pulsecore/sink-input.h>
-#include <pulsecore/source-output.h>
-#include <pulsecore/modargs.h>
#include <pulsecore/log.h>
#include <pulsecore/namereg.h>
#include <pulsecore/core-util.h>
PA_MODULE_AUTHOR("Lennart Poettering");
-PA_MODULE_DESCRIPTION("When a sink/source is removed, try to move its streams to the default sink/source");
+PA_MODULE_DESCRIPTION("This module is obsolete, please remove it from your configuration.");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(true);
-static const char* const valid_modargs[] = {
- NULL,
-};
-
-struct userdata {
- pa_hook_slot
- *sink_unlink_slot,
- *source_unlink_slot,
- *sink_input_move_fail_slot,
- *source_output_move_fail_slot;
-};
-
-static pa_source* find_source_from_port(pa_core *c, pa_device_port *port) {
- pa_source *target;
- uint32_t idx;
- void *state;
- pa_device_port *p;
-
- if (!port)
- return NULL;
-
- PA_IDXSET_FOREACH(target, c->sources, idx)
- PA_HASHMAP_FOREACH(p, target->ports, state)
- if (port == p)
- return target;
-
- return NULL;
-}
-
-static pa_sink* find_sink_from_port(pa_core *c, pa_device_port *port) {
- pa_sink *target;
- uint32_t idx;
- void *state;
- pa_device_port *p;
-
- if (!port)
- return NULL;
-
- PA_IDXSET_FOREACH(target, c->sinks, idx)
- PA_HASHMAP_FOREACH(p, target->ports, state)
- if (port == p)
- return target;
-
- return NULL;
-}
-
-static void build_group_ports(pa_hashmap *g_ports, pa_hashmap *s_ports) {
- void *state;
- pa_device_port *p;
-
- if (!g_ports || !s_ports)
- return;
-
- PA_HASHMAP_FOREACH(p, s_ports, state)
- pa_hashmap_put(g_ports, p, p);
-}
-
-static pa_sink* find_evacuation_sink(pa_core *c, pa_sink_input *i, pa_sink *skip) {
- pa_sink *target, *fb_sink = NULL;
- uint32_t idx;
- pa_hashmap *all_ports;
- pa_device_port *best_port;
-
- pa_assert(c);
- pa_assert(i);
-
- if (c->default_sink && c->default_sink != skip && pa_sink_input_may_move_to(i, c->default_sink))
- return c->default_sink;
-
- all_ports = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
-
- PA_IDXSET_FOREACH(target, c->sinks, idx) {
- if (target == c->default_sink)
- continue;
-
- if (target == skip)
- continue;
-
- if (!PA_SINK_IS_LINKED(target->state))
- continue;
-
- if (!pa_sink_input_may_move_to(i, target))
- continue;
-
- if (!fb_sink)
- fb_sink = target;
-
- build_group_ports(all_ports, target->ports);
- }
-
- best_port = pa_device_port_find_best(all_ports);
-
- pa_hashmap_free(all_ports);
-
- if (best_port)
- target = find_sink_from_port(c, best_port);
- else
- target = fb_sink;
-
- if (!target)
- pa_log_debug("No evacuation sink found.");
-
- return target;
-}
-
-static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
- pa_sink_input *i;
- uint32_t idx;
-
- pa_assert(c);
- pa_assert(sink);
-
- /* There's no point in doing anything if the core is shut down anyway */
- if (c->state == PA_CORE_SHUTDOWN)
- return PA_HOOK_OK;
-
- if (pa_idxset_size(sink->inputs) <= 0) {
- pa_log_debug("No sink inputs to move away.");
- return PA_HOOK_OK;
- }
-
- PA_IDXSET_FOREACH(i, sink->inputs, idx) {
- pa_sink *target;
-
- if (!(target = find_evacuation_sink(c, i, sink)))
- continue;
-
- if (pa_sink_input_move_to(i, target, false) < 0)
- pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- else
- pa_log_info("Successfully moved sink input %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- }
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_input_move_fail_hook_callback(pa_core *c, pa_sink_input *i, void *userdata) {
- pa_sink *target;
-
- pa_assert(c);
- pa_assert(i);
-
- /* There's no point in doing anything if the core is shut down anyway */
- if (c->state == PA_CORE_SHUTDOWN)
- return PA_HOOK_OK;
-
- if (!(target = find_evacuation_sink(c, i, NULL)))
- return PA_HOOK_OK;
-
- if (pa_sink_input_finish_move(i, target, false) < 0) {
- pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- return PA_HOOK_OK;
-
- } else {
- pa_log_info("Successfully moved sink input %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- return PA_HOOK_STOP;
- }
-}
-
-static pa_source* find_evacuation_source(pa_core *c, pa_source_output *o, pa_source *skip) {
- pa_source *target, *fb_source = NULL;
- uint32_t idx;
- pa_hashmap *all_ports;
- pa_device_port *best_port;
-
- pa_assert(c);
- pa_assert(o);
-
- if (c->default_source && c->default_source != skip && pa_source_output_may_move_to(o, c->default_source))
- return c->default_source;
-
- all_ports = pa_hashmap_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
-
- PA_IDXSET_FOREACH(target, c->sources, idx) {
- if (target == c->default_source)
- continue;
-
- if (target == skip)
- continue;
-
- /* We only move to a monitor source if we're already on one */
- if (skip && !target->monitor_of != !skip->monitor_of)
- continue;
-
- if (!PA_SOURCE_IS_LINKED(target->state))
- continue;
-
- if (!pa_source_output_may_move_to(o, target))
- continue;
-
- if (!fb_source)
- fb_source = target;
-
- build_group_ports(all_ports, target->ports);
- }
-
- best_port = pa_device_port_find_best(all_ports);
-
- pa_hashmap_free(all_ports);
-
- if (best_port)
- target = find_source_from_port(c, best_port);
- else
- target = fb_source;
-
- if (!target)
- pa_log_debug("No evacuation source found.");
-
- return target;
-}
-
-static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, void* userdata) {
- pa_source_output *o;
- uint32_t idx;
-
- pa_assert(c);
- pa_assert(source);
-
- /* There's no point in doing anything if the core is shut down anyway */
- if (c->state == PA_CORE_SHUTDOWN)
- return PA_HOOK_OK;
-
- if (pa_idxset_size(source->outputs) <= 0) {
- pa_log_debug("No source outputs to move away.");
- return PA_HOOK_OK;
- }
-
- PA_IDXSET_FOREACH(o, source->outputs, idx) {
- pa_source *target;
-
- if (!(target = find_evacuation_source(c, o, source)))
- continue;
-
- if (pa_source_output_move_to(o, target, false) < 0)
- pa_log_info("Failed to move source output %u \"%s\" to %s.", o->index,
- pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- else
- pa_log_info("Successfully moved source output %u \"%s\" to %s.", o->index,
- pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- }
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_output_move_fail_hook_callback(pa_core *c, pa_source_output *i, void *userdata) {
- pa_source *target;
-
- pa_assert(c);
- pa_assert(i);
-
- /* There's no point in doing anything if the core is shut down anyway */
- if (c->state == PA_CORE_SHUTDOWN)
- return PA_HOOK_OK;
-
- if (!(target = find_evacuation_source(c, i, NULL)))
- return PA_HOOK_OK;
-
- if (pa_source_output_finish_move(i, target, false) < 0) {
- pa_log_info("Failed to move source output %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- return PA_HOOK_OK;
-
- } else {
- pa_log_info("Successfully moved source output %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), target->name);
- return PA_HOOK_STOP;
- }
-}
int pa__init(pa_module*m) {
- pa_modargs *ma;
- struct userdata *u;
pa_assert(m);
- if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
- pa_log("Failed to parse module arguments");
- return -1;
- }
-
- m->userdata = u = pa_xnew(struct userdata, 1);
-
- /* A little bit later than module-stream-restore, module-intended-roles... */
- u->sink_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE+20, (pa_hook_cb_t) sink_unlink_hook_callback, u);
- u->source_unlink_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE+20, (pa_hook_cb_t) source_unlink_hook_callback, u);
+ pa_log("module-rescue-stream is obsolete and should no longer be loaded. Please remove it from your configuration.");
- u->sink_input_move_fail_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], PA_HOOK_LATE+20, (pa_hook_cb_t) sink_input_move_fail_hook_callback, u);
- u->source_output_move_fail_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL], PA_HOOK_LATE+20, (pa_hook_cb_t) source_output_move_fail_hook_callback, u);
+ pa_module_unload_request(m, false);
- pa_modargs_free(ma);
return 0;
}
-
-void pa__done(pa_module*m) {
- struct userdata *u;
-
- pa_assert(m);
-
- if (!(u = m->userdata))
- return;
-
- if (u->sink_unlink_slot)
- pa_hook_slot_free(u->sink_unlink_slot);
- if (u->source_unlink_slot)
- pa_hook_slot_free(u->source_unlink_slot);
-
- if (u->sink_input_move_fail_slot)
- pa_hook_slot_free(u->sink_input_move_fail_slot);
- if (u->source_output_move_fail_slot)
- pa_hook_slot_free(u->source_output_move_fail_slot);
-
- pa_xfree(u);
-}
diff --git a/src/modules/module-stream-restore.c b/src/modules/module-stream-restore.c
index cbef478..6a42466 100644
--- a/src/modules/module-stream-restore.c
+++ b/src/modules/module-stream-restore.c
@@ -64,8 +64,8 @@ PA_MODULE_USAGE(
"restore_device=<Save/restore sinks/sources?> "
"restore_volume=<Save/restore volumes?> "
"restore_muted=<Save/restore muted states?> "
- "on_hotplug=<When new device becomes available, recheck streams?> "
- "on_rescue=<When device becomes unavailable, recheck streams?> "
+ "on_hotplug=<This argument is obsolete, please remove it from configuration> "
+ "on_rescue=<This argument is obsolete, please remove it from configuration> "
"fallback_table=<filename>");
#define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
@@ -95,10 +95,6 @@ struct userdata {
*sink_input_fixate_hook_slot,
*source_output_new_hook_slot,
*source_output_fixate_hook_slot,
- *sink_put_hook_slot,
- *source_put_hook_slot,
- *sink_unlink_hook_slot,
- *source_unlink_hook_slot,
*connection_unlink_hook_slot;
pa_time_event *save_time_event;
pa_database* database;
@@ -106,8 +102,6 @@ struct userdata {
bool restore_device:1;
bool restore_volume:1;
bool restore_muted:1;
- bool on_hotplug:1;
- bool on_rescue:1;
pa_native_protocol *protocol;
pa_idxset *subscribed;
@@ -1311,19 +1305,24 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
}
- if (sink_input->save_sink) {
+ if (sink_input->preferred_sink != NULL || !created_new_entry) {
+ pa_sink *s = NULL;
+
pa_xfree(entry->device);
- entry->device = pa_xstrdup(sink_input->sink->name);
+ entry->device = pa_xstrdup(sink_input->preferred_sink);
entry->device_valid = true;
-
- device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
- if (sink_input->sink->card) {
- pa_xfree(entry->card);
- entry->card = pa_xstrdup(sink_input->sink->card->name);
+ if (!entry->device)
+ entry->device_valid = false;
+
+ device_updated = !created_new_entry && !pa_safe_streq(entry->device, old->device);
+ pa_xfree(entry->card);
+ entry->card = NULL;
+ entry->card_valid = false;
+ if (entry->device_valid && (s = pa_namereg_get(c, entry->device, PA_NAMEREG_SINK)) && s->card) {
+ entry->card = pa_xstrdup(s->card->name);
entry->card_valid = true;
}
}
-
} else {
pa_source_output *source_output;
@@ -1366,16 +1365,22 @@ static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint3
mute_updated = !created_new_entry && (!old->muted_valid || entry->muted != old->muted);
}
- if (source_output->save_source) {
+ if (source_output->preferred_source != NULL || !created_new_entry) {
+ pa_source *s = NULL;
+
pa_xfree(entry->device);
- entry->device = pa_xstrdup(source_output->source->name);
+ entry->device = pa_xstrdup(source_output->preferred_source);
entry->device_valid = true;
- device_updated = !created_new_entry && (!old->device_valid || !pa_streq(entry->device, old->device));
+ if (!entry->device)
+ entry->device_valid = false;
- if (source_output->source->card) {
- pa_xfree(entry->card);
- entry->card = pa_xstrdup(source_output->source->card->name);
+ device_updated = !created_new_entry && !pa_safe_streq(entry->device, old->device);
+ pa_xfree(entry->card);
+ entry->card = NULL;
+ entry->card_valid = false;
+ if (entry->device_valid && (s = pa_namereg_get(c, entry->device, PA_NAMEREG_SOURCE)) && s->card) {
+ entry->card = pa_xstrdup(s->card->name);
entry->card_valid = true;
}
}
@@ -1634,209 +1639,6 @@ static pa_hook_result_t source_output_fixate_hook_callback(pa_core *c, pa_source
return PA_HOOK_OK;
}
-static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
- pa_sink_input *si;
- uint32_t idx;
-
- pa_assert(c);
- pa_assert(sink);
- pa_assert(u);
- pa_assert(u->on_hotplug && u->restore_device);
-
- PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
- char *name;
- struct entry *e;
-
- if (si->sink == sink)
- continue;
-
- if (si->save_sink)
- continue;
-
- /* Skip this if it is already in the process of being moved
- * anyway */
- if (!si->sink)
- continue;
-
- /* Skip this sink input if it is connecting a filter sink to
- * the master */
- if (si->origin_sink)
- continue;
-
- /* It might happen that a stream and a sink are set up at the
- same time, in which case we want to make sure we don't
- interfere with that */
- if (!PA_SINK_INPUT_IS_LINKED(si->state))
- continue;
-
- if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
- continue;
-
- if ((e = entry_read(u, name))) {
- if (e->device_valid && pa_streq(e->device, sink->name))
- pa_sink_input_move_to(si, sink, true);
-
- entry_free(e);
- }
-
- pa_xfree(name);
- }
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
- pa_source_output *so;
- uint32_t idx;
-
- pa_assert(c);
- pa_assert(source);
- pa_assert(u);
- pa_assert(u->on_hotplug && u->restore_device);
-
- PA_IDXSET_FOREACH(so, c->source_outputs, idx) {
- char *name;
- struct entry *e;
-
- if (so->source == source)
- continue;
-
- if (so->save_source)
- continue;
-
- if (so->direct_on_input)
- continue;
-
- /* Skip this if it is already in the process of being moved anyway */
- if (!so->source)
- continue;
-
- /* Skip this source output if it is connecting a filter source to
- * the master */
- if (so->destination_source)
- continue;
-
- /* It might happen that a stream and a source are set up at the
- same time, in which case we want to make sure we don't
- interfere with that */
- if (!PA_SOURCE_OUTPUT_IS_LINKED(so->state))
- continue;
-
- if (!(name = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
- continue;
-
- if ((e = entry_read(u, name))) {
- if (e->device_valid && pa_streq(e->device, source->name))
- pa_source_output_move_to(so, source, true);
-
- entry_free(e);
- }
-
- pa_xfree(name);
- }
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t sink_unlink_hook_callback(pa_core *c, pa_sink *sink, struct userdata *u) {
- pa_sink_input *si;
- uint32_t idx;
-
- pa_assert(c);
- pa_assert(sink);
- pa_assert(u);
- pa_assert(u->on_rescue && u->restore_device);
-
- /* There's no point in doing anything if the core is shut down anyway */
- if (c->state == PA_CORE_SHUTDOWN)
- return PA_HOOK_OK;
-
- PA_IDXSET_FOREACH(si, sink->inputs, idx) {
- char *name;
- struct entry *e;
-
- if (!si->sink)
- continue;
-
- /* Skip this sink input if it is connecting a filter sink to
- * the master */
- if (si->origin_sink)
- continue;
-
- if (!(name = pa_proplist_get_stream_group(si->proplist, "sink-input", IDENTIFICATION_PROPERTY)))
- continue;
-
- if ((e = entry_read(u, name))) {
-
- if (e->device_valid) {
- pa_sink *d;
-
- if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SINK)) &&
- d != sink &&
- PA_SINK_IS_LINKED(d->state))
- pa_sink_input_move_to(si, d, true);
- }
-
- entry_free(e);
- }
-
- pa_xfree(name);
- }
-
- return PA_HOOK_OK;
-}
-
-static pa_hook_result_t source_unlink_hook_callback(pa_core *c, pa_source *source, struct userdata *u) {
- pa_source_output *so;
- uint32_t idx;
-
- pa_assert(c);
- pa_assert(source);
- pa_assert(u);
- pa_assert(u->on_rescue && u->restore_device);
-
- /* There's no point in doing anything if the core is shut down anyway */
- if (c->state == PA_CORE_SHUTDOWN)
- return PA_HOOK_OK;
-
- PA_IDXSET_FOREACH(so, source->outputs, idx) {
- char *name;
- struct entry *e;
-
- if (so->direct_on_input)
- continue;
-
- if (!so->source)
- continue;
-
- /* Skip this source output if it is connecting a filter source to
- * the master */
- if (so->destination_source)
- continue;
-
- if (!(name = pa_proplist_get_stream_group(so->proplist, "source-output", IDENTIFICATION_PROPERTY)))
- continue;
-
- if ((e = entry_read(u, name))) {
-
- if (e->device_valid) {
- pa_source *d;
-
- if ((d = pa_namereg_get(c, e->device, PA_NAMEREG_SOURCE)) &&
- d != source &&
- PA_SOURCE_IS_LINKED(d->state))
- pa_source_output_move_to(so, d, true);
- }
-
- entry_free(e);
- }
-
- pa_xfree(name);
- }
-
- return PA_HOOK_OK;
-}
-
static int fill_db(struct userdata *u, const char *filename) {
FILE *f;
int n = 0;
@@ -1951,21 +1753,16 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) {
if (u->restore_device) {
if (!e->device_valid) {
- if (si->save_sink) {
+ if (si->preferred_sink != NULL) {
pa_log_info("Ensuring device is not saved for stream %s.", name);
/* If the device is not valid we should make sure the
- save flag is cleared as the user may have specifically
+ preferred_sink is cleared as the user may have specifically
removed the sink element from the rule. */
- si->save_sink = false;
- /* This is cheating a bit. The sink input itself has not changed
- but the rules governing its routing have, so we fire this event
- such that other routing modules (e.g. module-device-manager)
- will pick up the change and reapply their routing */
- pa_subscription_post(si->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, si->index);
+ pa_sink_input_set_preferred_sink(si, NULL);
}
} else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SINK))) {
pa_log_info("Restoring device for stream %s.", name);
- pa_sink_input_move_to(si, s, true);
+ pa_sink_input_set_preferred_sink(si, s);
}
}
}
@@ -1999,21 +1796,16 @@ static void entry_apply(struct userdata *u, const char *name, struct entry *e) {
if (u->restore_device) {
if (!e->device_valid) {
- if (so->save_source) {
+ if (so->preferred_source != NULL) {
pa_log_info("Ensuring device is not saved for stream %s.", name);
/* If the device is not valid we should make sure the
- save flag is cleared as the user may have specifically
+ preferred_source is cleared as the user may have specifically
removed the source element from the rule. */
- so->save_source = false;
- /* This is cheating a bit. The source output itself has not changed
- but the rules governing its routing have, so we fire this event
- such that other routing modules (e.g. module-device-manager)
- will pick up the change and reapply their routing */
- pa_subscription_post(so->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, so->index);
+ pa_source_output_set_preferred_source(so, NULL);
}
} else if ((s = pa_namereg_get(u->core, e->device, PA_NAMEREG_SOURCE))) {
pa_log_info("Restoring device for stream %s.", name);
- pa_source_output_move_to(so, s, true);
+ pa_source_output_set_preferred_source(so, s);
}
}
}
@@ -2152,7 +1944,7 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
}
while (!pa_tagstruct_eof(t)) {
- const char *name, *device;
+ const char *name, *device, *client_name;
bool muted;
struct entry *entry;
#ifdef HAVE_DBUS
@@ -2193,7 +1985,20 @@ static int extension_cb(pa_native_protocol *p, pa_module *m, pa_native_connectio
entry_free(entry);
goto fail;
}
-
+ /* When users select an output device from gnome-control-center, the gnome-control-center will change all entries
+ * in the database to bind the sink of this output device, this is not correct since at this moment, the sink is
+ * default_sink and we shouldn't bind a stream to default_sink via preferred_sink or database. This also applies
+ * to source, default_source and preferred_source.
+ * After gnome-control-center fix the issue, let us remove this code */
+ client_name = pa_strnull(pa_proplist_gets(pa_native_connection_get_client(c)->proplist, PA_PROP_APPLICATION_PROCESS_BINARY));
+ if (pa_safe_streq(client_name, "gnome-control-center")) {
+ if (entry->device_valid && ((m->core->default_sink && pa_safe_streq(device, m->core->default_sink->name)) ||
+ (m->core->default_source && pa_safe_streq(device, m->core->default_source->name)))) {
+ entry_free(entry);
+ pa_pstream_send_tagstruct(pa_native_connection_get_pstream(c), reply);
+ return 0;
+ }
+ }
#ifdef HAVE_DBUS
old = entry_read(u, name);
#endif
@@ -2415,7 +2220,8 @@ int pa__init(pa_module*m) {
pa_sink_input *si;
pa_source_output *so;
uint32_t idx;
- bool restore_device = true, restore_volume = true, restore_muted = true, on_hotplug = true, on_rescue = true;
+ bool restore_device = true, restore_volume = true, restore_muted = true;
+
#ifdef HAVE_DBUS
pa_datum key;
bool done;
@@ -2430,13 +2236,15 @@ int pa__init(pa_module*m) {
if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 ||
pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0 ||
- pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0 ||
- pa_modargs_get_value_boolean(ma, "on_hotplug", &on_hotplug) < 0 ||
- pa_modargs_get_value_boolean(ma, "on_rescue", &on_rescue) < 0) {
- pa_log("restore_device=, restore_volume=, restore_muted=, on_hotplug= and on_rescue= expect boolean arguments");
+ pa_modargs_get_value_boolean(ma, "restore_muted", &restore_muted) < 0) {
+ pa_log("restore_device=, restore_volume= and restore_muted= expect boolean arguments");
goto fail;
}
+ if (pa_modargs_get_value(ma, "on_hotplug", NULL) != NULL ||
+ pa_modargs_get_value(ma, "on_rescue", NULL) != NULL)
+ pa_log("on_hotplug and on_rescue are obsolete arguments, please remove them from your configuration");
+
if (!restore_muted && !restore_volume && !restore_device)
pa_log_warn("Neither restoring volume, nor restoring muted, nor restoring device enabled!");
@@ -2446,8 +2254,6 @@ int pa__init(pa_module*m) {
u->restore_device = restore_device;
u->restore_volume = restore_volume;
u->restore_muted = restore_muted;
- u->on_hotplug = on_hotplug;
- u->on_rescue = on_rescue;
u->subscribed = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func);
u->protocol = pa_native_protocol_get(m->core);
@@ -2463,18 +2269,6 @@ int pa__init(pa_module*m) {
pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_NEW], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_new_hook_callback, u);
}
- if (restore_device && on_hotplug) {
- /* A little bit earlier than module-intended-roles ... */
- pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE, (pa_hook_cb_t) sink_put_hook_callback, u);
- pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE, (pa_hook_cb_t) source_put_hook_callback, u);
- }
-
- if (restore_device && on_rescue) {
- /* A little bit earlier than module-intended-roles, module-rescue-streams, ... */
- pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) sink_unlink_hook_callback, u);
- pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_UNLINK], PA_HOOK_LATE, (pa_hook_cb_t) source_unlink_hook_callback, u);
- }
-
if (restore_volume || restore_muted) {
pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) sink_input_fixate_hook_callback, u);
pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_FIXATE], PA_HOOK_EARLY, (pa_hook_cb_t) source_output_fixate_hook_callback, u);
diff --git a/src/modules/module-switch-on-connect.c b/src/modules/module-switch-on-connect.c
index 9077eae..950ecbe 100644
--- a/src/modules/module-switch-on-connect.c
+++ b/src/modules/module-switch-on-connect.c
@@ -33,6 +33,12 @@
#include <pulsecore/namereg.h>
#include <pulsecore/core-util.h>
+/* Ignore HDMI devices by default. HDMI monitors don't necessarily have audio
+ * output on them, and even if they do, waking up from sleep or changing
+ * monitor resolution may appear as a plugin event, which causes trouble if the
+ * user doesn't want to use the monitor for audio. */
+#define DEFAULT_BLACKLIST "hdmi"
+
PA_MODULE_AUTHOR("Michael Terry");
PA_MODULE_DESCRIPTION("When a sink/source is added, switch to it or conditionally switch to it");
PA_MODULE_VERSION(PACKAGE_VERSION);
@@ -40,23 +46,23 @@ PA_MODULE_LOAD_ONCE(true);
PA_MODULE_USAGE(
"only_from_unavailable=<boolean, only switch from unavailable ports> "
"ignore_virtual=<boolean, ignore new virtual sinks and sources, defaults to true> "
+ "blacklist=<regex, ignore matching devices> "
);
static const char* const valid_modargs[] = {
"only_from_unavailable",
"ignore_virtual",
+ "blacklist",
NULL,
};
struct userdata {
bool only_from_unavailable;
bool ignore_virtual;
+ char *blacklist;
};
static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
- pa_sink_input *i;
- uint32_t idx;
- pa_sink *old_default_sink;
const char *s;
struct userdata *u = userdata;
@@ -80,6 +86,12 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
}
}
+ /* Ignore sinks matching the blacklist regex */
+ if (u->blacklist && (pa_match(u->blacklist, sink->name) > 0)) {
+ pa_log_info("Refusing to switch to blacklisted sink %s", sink->name);
+ return PA_HOOK_OK;
+ }
+
/* Ignore virtual sinks if not configured otherwise on the command line */
if (u->ignore_virtual && !(sink->flags & PA_SINK_HARDWARE)) {
pa_log_debug("Refusing to switch to virtual sink");
@@ -103,36 +115,13 @@ static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void*
return PA_HOOK_OK;
}
- old_default_sink = c->default_sink;
-
/* Actually do the switch to the new sink */
pa_core_set_configured_default_sink(c, sink->name);
- /* Now move all old inputs over */
- if (pa_idxset_size(old_default_sink->inputs) <= 0) {
- pa_log_debug("No sink inputs to move away.");
- return PA_HOOK_OK;
- }
-
- PA_IDXSET_FOREACH(i, old_default_sink->inputs, idx) {
- if (i->save_sink || !PA_SINK_INPUT_IS_LINKED(i->state))
- continue;
-
- if (pa_sink_input_move_to(i, sink, false) < 0)
- pa_log_info("Failed to move sink input %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), sink->name);
- else
- pa_log_info("Successfully moved sink input %u \"%s\" to %s.", i->index,
- pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), sink->name);
- }
-
return PA_HOOK_OK;
}
static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source, void* userdata) {
- pa_source_output *o;
- uint32_t idx;
- pa_source *old_default_source;
const char *s;
struct userdata *u = userdata;
@@ -157,6 +146,12 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
return PA_HOOK_OK;
}
+ /* Ignore sources matching the blacklist regex */
+ if (u->blacklist && (pa_match(u->blacklist, source->name) > 0)) {
+ pa_log_info("Refusing to switch to blacklisted source %s", source->name);
+ return PA_HOOK_OK;
+ }
+
/* Ignore virtual sources if not configured otherwise on the command line */
if (u->ignore_virtual && !(source->flags & PA_SOURCE_HARDWARE)) {
pa_log_debug("Refusing to switch to virtual source");
@@ -180,29 +175,9 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
return PA_HOOK_OK;
}
- old_default_source = c->default_source;
-
/* Actually do the switch to the new source */
pa_core_set_configured_default_source(c, source->name);
- /* Now move all old outputs over */
- if (pa_idxset_size(old_default_source->outputs) <= 0) {
- pa_log_debug("No source outputs to move away.");
- return PA_HOOK_OK;
- }
-
- PA_IDXSET_FOREACH(o, old_default_source->outputs, idx) {
- if (o->save_source || !PA_SOURCE_OUTPUT_IS_LINKED(o->state))
- continue;
-
- if (pa_source_output_move_to(o, source, false) < 0)
- pa_log_info("Failed to move source output %u \"%s\" to %s.", o->index,
- pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), source->name);
- else
- pa_log_info("Successfully moved source output %u \"%s\" to %s.", o->index,
- pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), source->name);
- }
-
return PA_HOOK_OK;
}
@@ -219,7 +194,6 @@ int pa__init(pa_module*m) {
m->userdata = u = pa_xnew0(struct userdata, 1);
- /* A little bit later than module-rescue-streams... */
pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_LATE+30, (pa_hook_cb_t) sink_put_hook_callback, u);
pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_LATE+20, (pa_hook_cb_t) source_put_hook_callback, u);
@@ -234,6 +208,20 @@ int pa__init(pa_module*m) {
goto fail;
}
+ u->blacklist = pa_xstrdup(pa_modargs_get_value(ma, "blacklist", DEFAULT_BLACKLIST));
+
+ /* An empty string disables all blacklisting. */
+ if (!*u->blacklist) {
+ pa_xfree(u->blacklist);
+ u->blacklist = NULL;
+ }
+
+ if (u->blacklist != NULL && !pa_is_regex_valid(u->blacklist)) {
+ pa_log_error("A blacklist pattern was provided but is not a valid regex");
+ pa_xfree(u->blacklist);
+ goto fail;
+ }
+
pa_modargs_free(ma);
return 0;
@@ -254,5 +242,8 @@ void pa__done(pa_module*m) {
if (!(u = m->userdata))
return;
+ if (u->blacklist)
+ pa_xfree(u->blacklist);
+
pa_xfree(u);
}
diff --git a/src/modules/module-virtual-source.c b/src/modules/module-virtual-source.c
index 0c98178..22566b0 100644
--- a/src/modules/module-virtual-source.c
+++ b/src/modules/module-virtual-source.c
@@ -152,18 +152,6 @@ static void sink_update_requested_latency_cb(pa_sink *s) {
}
/* Called from I/O thread context */
-static void sink_request_rewind_cb(pa_sink *s) {
- struct userdata *u;
-
- pa_sink_assert_ref(s);
- pa_assert_se(u = s->userdata);
-
- /* Do nothing */
- pa_sink_process_rewind(u->sink, 0);
-
-}
-
-/* Called from I/O thread context */
static int source_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
struct userdata *u = PA_SOURCE(o)->userdata;
@@ -458,6 +446,8 @@ static void source_output_kill_cb(pa_source_output *o) {
/* Called from main thread */
static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
struct userdata *u;
+ uint32_t idx;
+ pa_source_output *output;
pa_source_output_assert_ref(o);
pa_assert_ctl_context();
@@ -469,6 +459,12 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
} else
pa_source_set_asyncmsgq(u->source, NULL);
+ /* Propagate asyncmsq change to attached virtual sources */
+ PA_IDXSET_FOREACH(output, u->source->outputs, idx) {
+ if (output->destination_source && output->moving)
+ output->moving(output, u->source);
+ }
+
if (u->auto_desc && dest) {
const char *z;
pa_proplist *pl;
@@ -675,7 +671,6 @@ int pa__init(pa_module*m) {
u->sink->parent.process_msg = sink_process_msg_cb;
u->sink->update_requested_latency = sink_update_requested_latency_cb;
- u->sink->request_rewind = sink_request_rewind_cb;
u->sink->set_state_in_main_thread = sink_set_state_in_main_thread_cb;
u->sink->userdata = u;
@@ -685,7 +680,7 @@ int pa__init(pa_module*m) {
/* FIXME: no idea what I am doing here */
u->block_usec = BLOCK_USEC;
nbytes = pa_usec_to_bytes(u->block_usec, &u->sink->sample_spec);
- pa_sink_set_max_rewind(u->sink, nbytes);
+ pa_sink_set_max_rewind(u->sink, 0);
pa_sink_set_max_request(u->sink, nbytes);
pa_sink_put(u->sink);
diff --git a/src/modules/module-virtual-surround-sink.c b/src/modules/module-virtual-surround-sink.c
index d8e0fd9..c321073 100644
--- a/src/modules/module-virtual-surround-sink.c
+++ b/src/modules/module-virtual-surround-sink.c
@@ -786,7 +786,7 @@ int pa__init(pa_module*m) {
u->sink->input_to_master = u->sink_input;
pa_sink_input_get_silence(u->sink_input, &silence);
- u->memblockq = pa_memblockq_new("module-virtual-surround-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &sink_input_ss, 1, 1, 0, &silence);
+ u->memblockq = pa_memblockq_new("module-virtual-surround-sink memblockq", 0, MEMBLOCKQ_MAXLENGTH, 0, &ss, 1, 1, 0, &silence);
pa_memblock_unref(silence.memblock);
/* resample hrir */
diff --git a/src/modules/raop/meson.build b/src/modules/raop/meson.build
index e98bb45..533580c 100644
--- a/src/modules/raop/meson.build
+++ b/src/modules/raop/meson.build
@@ -23,7 +23,7 @@ libraop = shared_library('raop',
c_args : [pa_c_args, server_c_args],
link_args : [nodelete_link_args],
include_directories : [configinc, topinc],
- dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, librtp_dep, openssl_dep],
+ dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, librtp_dep, openssl_dep, libintl_dep],
install : true,
install_rpath : rpath_dirs,
install_dir : modlibexecdir,
diff --git a/src/modules/raop/module-raop-sink.c b/src/modules/raop/module-raop-sink.c
index 745b1d0..393341a 100644
--- a/src/modules/raop/module-raop-sink.c
+++ b/src/modules/raop/module-raop-sink.c
@@ -58,9 +58,11 @@ static const char* const valid_modargs[] = {
"format",
"rate",
"channels",
+ "channel_map",
"username",
"password",
"latency_msec",
+ "autoreconnect",
NULL
};
diff --git a/src/modules/raop/raop-client.c b/src/modules/raop/raop-client.c
index 4887e0f..9a026db 100644
--- a/src/modules/raop/raop-client.c
+++ b/src/modules/raop/raop-client.c
@@ -95,6 +95,7 @@ struct pa_raop_client {
pa_rtsp_client *rtsp;
char *sci, *sid;
char *password;
+ bool autoreconnect;
pa_raop_protocol_t protocol;
pa_raop_encryption_t encryption;
@@ -362,13 +363,12 @@ static ssize_t send_tcp_audio_packet(pa_raop_client *c, pa_memchunk *block, size
ssize_t written = -1;
size_t done = 0;
- if (!(packet = pa_raop_packet_buffer_retrieve(c->pbuf, c->seq)))
- return -1;
+ packet = pa_raop_packet_buffer_retrieve(c->pbuf, c->seq);
- if (packet->length <= 0) {
+ if (!packet || (packet && packet->length <= 0)) {
pa_assert(block->index == offset);
- if (!(packet = pa_raop_packet_buffer_prepare(c->pbuf, c->seq + 1, max)))
+ if (!(packet = pa_raop_packet_buffer_prepare(c->pbuf, c->seq, max)))
return -1;
packet->index = 0;
@@ -1326,10 +1326,11 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_st
c->password = NULL;
}
- if (c->state_callback)
- c->state_callback((int) PA_RAOP_AUTHENTICATED, c->state_userdata);
pa_rtsp_client_free(c->rtsp);
c->rtsp = NULL;
+ /* Ensure everything is cleaned before calling the callback, otherwise it may raise a crash */
+ if (c->state_callback)
+ c->state_callback((int) PA_RAOP_AUTHENTICATED, c->state_userdata);
waiting = false;
break;
@@ -1379,8 +1380,39 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_st
}
}
+
+void pa_raop_client_disconnect(pa_raop_client *c) {
+ c->is_recording = false;
+
+ if (c->tcp_sfd >= 0)
+ pa_close(c->tcp_sfd);
+ c->tcp_sfd = -1;
+
+ if (c->udp_sfd >= 0)
+ pa_close(c->udp_sfd);
+ c->udp_sfd = -1;
+
+ /* Polling sockets will be closed by sink */
+ c->udp_cfd = c->udp_tfd = -1;
+ c->tcp_sfd = -1;
+
+ pa_log_error("RTSP control channel closed (disconnected)");
+
+ if (c->rtsp)
+ pa_rtsp_client_free(c->rtsp);
+ if (c->sid)
+ pa_xfree(c->sid);
+ c->rtsp = NULL;
+ c->sid = NULL;
+
+ if (c->state_callback)
+ c->state_callback((int) PA_RAOP_DISCONNECTED, c->state_userdata);
+
+}
+
+
pa_raop_client* pa_raop_client_new(pa_core *core, const char *host, pa_raop_protocol_t protocol,
- pa_raop_encryption_t encryption, pa_raop_codec_t codec) {
+ pa_raop_encryption_t encryption, pa_raop_codec_t codec, bool autoreconnect) {
pa_raop_client *c;
pa_parsed_address a;
@@ -1408,6 +1440,7 @@ pa_raop_client* pa_raop_client_new(pa_core *core, const char *host, pa_raop_prot
c->rtsp = NULL;
c->sci = c->sid = NULL;
c->password = NULL;
+ c->autoreconnect = autoreconnect;
c->protocol = protocol;
c->encryption = encryption;
@@ -1473,7 +1506,7 @@ int pa_raop_client_authenticate (pa_raop_client *c, const char *password) {
c->password = NULL;
if (password)
c->password = pa_xstrdup(password);
- c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, DEFAULT_USER_AGENT);
+ c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, DEFAULT_USER_AGENT, c->autoreconnect);
pa_assert(c->rtsp);
@@ -1502,7 +1535,7 @@ int pa_raop_client_announce(pa_raop_client *c) {
return 1;
}
- c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, DEFAULT_USER_AGENT);
+ c->rtsp = pa_rtsp_client_new(c->core->mainloop, c->host, c->port, DEFAULT_USER_AGENT, c->autoreconnect);
pa_assert(c->rtsp);
@@ -1545,7 +1578,6 @@ bool pa_raop_client_can_stream(pa_raop_client *c) {
pa_assert(c);
if (!c->rtsp || !c->sci) {
- pa_log_debug("Can't stream, connection not established yet...");
return false;
}
@@ -1565,6 +1597,10 @@ bool pa_raop_client_can_stream(pa_raop_client *c) {
return false;
}
+bool pa_raop_client_is_recording(pa_raop_client *c) {
+ return c->is_recording;
+}
+
int pa_raop_client_stream(pa_raop_client *c) {
int rv = 0;
@@ -1725,6 +1761,10 @@ bool pa_raop_client_register_pollfd(pa_raop_client *c, pa_rtpoll *poll, pa_rtpol
return oob;
}
+bool pa_raop_client_is_timing_fd(pa_raop_client *c, const int fd) {
+ return fd == c->udp_tfd;
+}
+
pa_volume_t pa_raop_client_adjust_volume(pa_raop_client *c, pa_volume_t volume) {
double minv, maxv;
diff --git a/src/modules/raop/raop-client.h b/src/modules/raop/raop-client.h
index 72e6018..faec01e 100644
--- a/src/modules/raop/raop-client.h
+++ b/src/modules/raop/raop-client.h
@@ -57,7 +57,7 @@ typedef enum pa_raop_state {
} pa_raop_state_t;
pa_raop_client* pa_raop_client_new(pa_core *core, const char *host, pa_raop_protocol_t protocol,
- pa_raop_encryption_t encryption, pa_raop_codec_t codec);
+ pa_raop_encryption_t encryption, pa_raop_codec_t codec, bool autoreconnect);
void pa_raop_client_free(pa_raop_client *c);
int pa_raop_client_authenticate(pa_raop_client *c, const char *password);
@@ -65,14 +65,17 @@ bool pa_raop_client_is_authenticated(pa_raop_client *c);
int pa_raop_client_announce(pa_raop_client *c);
bool pa_raop_client_is_alive(pa_raop_client *c);
+bool pa_raop_client_is_recording(pa_raop_client *c);
bool pa_raop_client_can_stream(pa_raop_client *c);
int pa_raop_client_stream(pa_raop_client *c);
int pa_raop_client_set_volume(pa_raop_client *c, pa_volume_t volume);
int pa_raop_client_flush(pa_raop_client *c);
int pa_raop_client_teardown(pa_raop_client *c);
+void pa_raop_client_disconnect(pa_raop_client *c);
void pa_raop_client_get_frames_per_block(pa_raop_client *c, size_t *size);
bool pa_raop_client_register_pollfd(pa_raop_client *c, pa_rtpoll *poll, pa_rtpoll_item **poll_item);
+bool pa_raop_client_is_timing_fd(pa_raop_client *c, const int fd);
pa_volume_t pa_raop_client_adjust_volume(pa_raop_client *c, pa_volume_t volume);
void pa_raop_client_handle_oob_packet(pa_raop_client *c, const int fd, const uint8_t packet[], ssize_t size);
ssize_t pa_raop_client_send_audio_packet(pa_raop_client *c, pa_memchunk *block, size_t offset);
diff --git a/src/modules/raop/raop-sink.c b/src/modules/raop/raop-sink.c
index d5ce6dc..aa66af2 100644
--- a/src/modules/raop/raop-sink.c
+++ b/src/modules/raop/raop-sink.c
@@ -59,12 +59,16 @@
#include <pulsecore/thread-mq.h>
#include <pulsecore/poll.h>
#include <pulsecore/rtpoll.h>
+#include <pulsecore/core-rtclock.h>
#include <pulsecore/time-smoother.h>
#include "raop-sink.h"
#include "raop-client.h"
#include "raop-util.h"
+#define UDP_TIMING_PACKET_LOSS_MAX (30 * PA_USEC_PER_SEC)
+#define UDP_TIMING_PACKET_DISCONNECT_CYCLE 3
+
struct userdata {
pa_core *core;
pa_module *module;
@@ -78,11 +82,16 @@ struct userdata {
bool oob;
pa_raop_client *raop;
+ char *server;
pa_raop_protocol_t protocol;
pa_raop_encryption_t encryption;
pa_raop_codec_t codec;
+ bool autoreconnect;
+ /* if true, behaves like a null-sink when disconnected */
+ bool autonull;
size_t block_size;
+ pa_usec_t block_usec;
pa_memchunk memchunk;
pa_usec_t delay;
@@ -91,10 +100,13 @@ struct userdata {
uint64_t write_count;
uint32_t latency;
+ /* Consider as first I/O thread iteration, can be switched to true in autoreconnect mode */
+ bool first;
};
enum {
- PA_SINK_MESSAGE_SET_RAOP_STATE = PA_SINK_MESSAGE_MAX
+ PA_SINK_MESSAGE_SET_RAOP_STATE = PA_SINK_MESSAGE_MAX,
+ PA_SINK_MESSAGE_DISCONNECT_REQUEST
};
static void userdata_free(struct userdata *u);
@@ -136,10 +148,23 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_assert(u->raop);
switch (code) {
+ /* Exception : for this message, we are in main thread, msg sent from the IO/thread
+ Done here, as alloc/free of rtsp_client is also done in this thread for other cases */
+ case PA_SINK_MESSAGE_DISCONNECT_REQUEST: {
+ if (u->sink->state == PA_SINK_RUNNING) {
+ /* Disconnect raop client, and restart the whole chain since
+ * the authentication token might be outdated */
+ pa_raop_client_disconnect(u->raop);
+ pa_raop_client_authenticate(u->raop, NULL);
+ }
+
+ return 0;
+ }
+
case PA_SINK_MESSAGE_GET_LATENCY: {
int64_t r = 0;
- if (pa_raop_client_can_stream(u->raop))
+ if (u->autonull || pa_raop_client_can_stream(u->raop))
r = sink_get_latency(u);
*((int64_t*) data) = r;
@@ -154,6 +179,17 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_module_unload_request(u->module, true);
}
+ if (u->autoreconnect && u->sink->state == PA_SINK_RUNNING) {
+ pa_usec_t now;
+ now = pa_rtclock_now();
+ pa_smoother_reset(u->smoother, now, false);
+
+ if (!pa_raop_client_is_alive(u->raop)) {
+ /* Connecting will trigger a RECORD and start steaming */
+ pa_raop_client_announce(u->raop);
+ }
+ }
+
return 0;
}
@@ -169,9 +205,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
pa_usec_t now;
now = pa_rtclock_now();
- pa_rtpoll_set_timer_absolute(u->rtpoll, now);
u->write_count = 0;
u->start = now;
+ u->first = true;
+ pa_rtpoll_set_timer_absolute(u->rtpoll, now);
if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
/* Our stream has been suspended so we just flush it... */
@@ -180,6 +217,7 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
} else {
/* Set the initial volume */
sink_set_volume_cb(u->sink);
+ pa_sink_process_msg(o, PA_SINK_MESSAGE_SET_VOLUME, data, offset, chunk);
}
return 0;
@@ -204,10 +242,22 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
u->rtpoll_item = NULL;
}
- if (u->sink->thread_info.state == PA_SINK_SUSPENDED)
+ if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
pa_rtpoll_set_timer_disabled(u->rtpoll);
- else if (u->sink->thread_info.state != PA_SINK_IDLE)
- pa_module_unload_request(u->module, true);
+
+ return 0;
+ }
+
+ if (u->autoreconnect) {
+ if (u->sink->thread_info.state != PA_SINK_IDLE) {
+ if (!u->autonull)
+ pa_rtpoll_set_timer_disabled(u->rtpoll);
+ pa_raop_client_authenticate(u->raop, NULL);
+ }
+ } else {
+ if (u->sink->thread_info.state != PA_SINK_IDLE)
+ pa_module_unload_request(u->module, true);
+ }
return 0;
}
@@ -264,10 +314,19 @@ static int sink_set_state_in_io_thread_cb(pa_sink *s, pa_sink_state_t new_state,
now = pa_rtclock_now();
pa_smoother_reset(u->smoother, now, false);
+ /* If autonull is enabled, I/O thread is always eating chunks since
+ * it is emulating a null sink */
+ if (u->autonull) {
+ u->start = now;
+ u->write_count = 0;
+ u->first = true;
+ pa_rtpoll_set_timer_absolute(u->rtpoll, now);
+ }
+
if (!pa_raop_client_is_alive(u->raop)) {
- /* Connecting will trigger a RECORD and start steaming */
+ /* Connecting will trigger a RECORD and start streaming */
pa_raop_client_announce(u->raop);
- } else if (!pa_raop_client_can_stream(u->raop)) {
+ } else if (!pa_raop_client_is_recording(u->raop)) {
/* RECORD alredy sent, simply start streaming */
pa_raop_client_stream(u->raop);
pa_rtpoll_set_timer_absolute(u->rtpoll, now);
@@ -341,6 +400,8 @@ static void sink_set_mute_cb(pa_sink *s) {
static void thread_func(void *userdata) {
struct userdata *u = userdata;
size_t offset = 0;
+ pa_usec_t last_timing;
+ uint32_t check_timing_count;
pa_assert(u);
@@ -356,11 +417,7 @@ static void thread_func(void *userdata) {
uint64_t position;
size_t index;
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);
- }
+ bool canstream, sendstream, on_timeout;
/* Polling (audio data + control socket + timing socket). */
if ((ret = pa_rtpoll_run(u->rtpoll)) < 0)
@@ -368,6 +425,12 @@ static void thread_func(void *userdata) {
else if (ret == 0)
goto finish;
+ if (PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
+ if (u->sink->thread_info.rewind_requested)
+ pa_sink_process_rewind(u->sink, 0);
+ }
+
+ on_timeout = pa_rtpoll_timer_elapsed(u->rtpoll);
if (u->rtpoll_item) {
pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, &nbfds);
/* If !oob: streaming driven by pollds (POLLOUT) */
@@ -383,12 +446,19 @@ static void thread_func(void *userdata) {
}
/* if oob: streaming managed by timing, pollfd for oob sockets */
- if (pollfd && u->oob && !pa_rtpoll_timer_elapsed(u->rtpoll)) {
+ if (pollfd && u->oob && !on_timeout) {
uint8_t packet[32];
ssize_t read;
for (i = 0; i < nbfds; i++) {
if (pollfd->revents & POLLERR) {
+ if (u->autoreconnect && pa_raop_client_is_alive(u->raop)) {
+ pollfd->revents = 0;
+ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->sink),
+ PA_SINK_MESSAGE_DISCONNECT_REQUEST, 0, 0, NULL, NULL);
+ continue;
+ }
+
/* one of UDP fds is in faulty state, may have been disconnected, this is fatal */
goto fail;
}
@@ -396,6 +466,10 @@ static void thread_func(void *userdata) {
pollfd->revents = 0;
read = pa_read(pollfd->fd, packet, sizeof(packet), NULL);
pa_raop_client_handle_oob_packet(u->raop, pollfd->fd, packet, read);
+ if (pa_raop_client_is_timing_fd(u->raop, pollfd->fd)) {
+ last_timing = pa_rtclock_now();
+ check_timing_count = 1;
+ }
}
pollfd++;
@@ -405,65 +479,133 @@ static void thread_func(void *userdata) {
}
}
- if (u->sink->thread_info.state != PA_SINK_RUNNING)
- continue;
- if (!pa_raop_client_can_stream(u->raop))
+ if (u->sink->thread_info.state != PA_SINK_RUNNING) {
continue;
+ }
- /* This assertion is meant to silence a complaint from Coverity about
- * pollfd being possibly NULL when we access it later. That's a false
- * positive, because we check pa_raop_client_can_stream() above, and if
- * that returns true, it means that the connection is up, and when the
- * connection is up, pollfd will be non-NULL. */
- pa_assert(pollfd);
+ if (u->first) {
+ last_timing = 0;
+ check_timing_count = 1;
+ intvl = 0;
+ u->first = false;
+ }
- if (u->memchunk.length <= 0) {
- if (u->memchunk.memblock)
- pa_memblock_unref(u->memchunk.memblock);
- pa_memchunk_reset(&u->memchunk);
+ canstream = pa_raop_client_can_stream(u->raop);
+ now = pa_rtclock_now();
+
+ if (u->oob && u->autoreconnect && on_timeout) {
+ if (!canstream) {
+ last_timing = 0;
+ } else if (last_timing != 0) {
+ pa_usec_t since = now - last_timing;
+ /* Incoming Timing packets should be received every 3 seconds in UDP mode
+ according to raop specifications.
+ Here we disconnect if no packet received since UDP_TIMING_PACKET_LOSS_MAX seconds
+ We only detect timing packet requests interruptions (we do nothing if no packet received at all), since some clients do not implement RTCP Timing requests at all */
+
+ if (since > (UDP_TIMING_PACKET_LOSS_MAX/UDP_TIMING_PACKET_DISCONNECT_CYCLE)*check_timing_count) {
+ if (check_timing_count < UDP_TIMING_PACKET_DISCONNECT_CYCLE) {
+ uint32_t since_in_sec = since / PA_USEC_PER_SEC;
+ pa_log_warn(
+ "UDP Timing Packets Warn #%d/%d- Nothing received since %d seconds from %s",
+ check_timing_count,
+ UDP_TIMING_PACKET_DISCONNECT_CYCLE-1, since_in_sec, u->server);
+ check_timing_count++;
+ } else {
+ /* Limit reached, then request disconnect */
+ check_timing_count = 1;
+ last_timing = 0;
+ if (pa_raop_client_is_alive(u->raop)) {
+ pa_log_warn("UDP Timing Packets Warn limit reached - Requesting reconnect");
+ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->sink),
+ PA_SINK_MESSAGE_DISCONNECT_REQUEST, 0, 0, NULL, NULL);
+ continue;
+ }
+ }
+ }
+ }
+ }
- /* Grab unencoded audio data from PulseAudio */
- pa_sink_render_full(u->sink, u->block_size, &u->memchunk);
- offset = u->memchunk.index;
+ if (!u->autonull) {
+ if (!canstream) {
+ pa_log_debug("Can't stream, connection not established yet...");
+ continue;
+ }
+ /* This assertion is meant to silence a complaint from Coverity about
+ * pollfd being possibly NULL when we access it later. That's a false
+ * positive, because we check pa_raop_client_can_stream() above, and if
+ * that returns true, it means that the connection is up, and when the
+ * connection is up, pollfd will be non-NULL. */
+ pa_assert(pollfd);
}
- pa_assert(u->memchunk.length > 0);
-
- index = u->memchunk.index;
- if (pa_raop_client_send_audio_packet(u->raop, &u->memchunk, offset) < 0) {
- if (errno == EINTR) {
- /* Just try again. */
- pa_log_debug("Failed to write data to FIFO (EINTR), retrying");
- goto fail;
- } else if (errno != EAGAIN && !u->oob) {
- /* Buffer is full, wait for POLLOUT. */
- pollfd->events = POLLOUT;
- pollfd->revents = 0;
- } else {
- pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno));
- goto fail;
+ if (u->memchunk.length <= 0) {
+ if (intvl < now + u->block_usec) {
+ if (u->memchunk.memblock)
+ pa_memblock_unref(u->memchunk.memblock);
+ pa_memchunk_reset(&u->memchunk);
+
+ /* Grab unencoded audio data from PulseAudio */
+ pa_sink_render_full(u->sink, u->block_size, &u->memchunk);
+ offset = u->memchunk.index;
}
- } else {
- u->write_count += (uint64_t) u->memchunk.index - (uint64_t) index;
- position = u->write_count - pa_usec_to_bytes(u->delay, &u->sink->sample_spec);
+ }
- now = pa_rtclock_now();
- estimated = pa_bytes_to_usec(position, &u->sink->sample_spec);
- pa_smoother_put(u->smoother, now, estimated);
-
- if (u->oob && !pollfd->revents) {
- /* Sleep until next packet transmission */
- intvl = u->start + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec);
- pa_rtpoll_set_timer_absolute(u->rtpoll, intvl);
- } else if (!u->oob) {
- if (u->memchunk.length > 0) {
- pollfd->events = POLLOUT;
- pollfd->revents = 0;
+ if (u->memchunk.length > 0) {
+ index = u->memchunk.index;
+ sendstream = !u->autonull || (u->autonull && canstream);
+ if (sendstream && pa_raop_client_send_audio_packet(u->raop, &u->memchunk, offset) < 0) {
+ if (errno == EINTR) {
+ /* Just try again. */
+ pa_log_debug("Failed to write data to FIFO (EINTR), retrying");
+ if (u->autoreconnect) {
+ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_DISCONNECT_REQUEST,
+ 0, 0, NULL, NULL);
+ continue;
+ } else
+ goto fail;
+ } else if (errno != EAGAIN && !u->oob) {
+ /* Buffer is full, wait for POLLOUT. */
+ if (!u->oob) {
+ pollfd->events = POLLOUT;
+ pollfd->revents = 0;
+ }
} else {
+ pa_log("Failed to write data to FIFO: %s", pa_cstrerror(errno));
+ if (u->autoreconnect) {
+ pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->sink), PA_SINK_MESSAGE_DISCONNECT_REQUEST,
+ 0, 0, NULL, NULL);
+ continue;
+ } else
+ goto fail;
+ }
+ } else {
+ if (sendstream) {
+ u->write_count += (uint64_t) u->memchunk.index - (uint64_t) index;
+ } else {
+ u->write_count += u->memchunk.length;
+ u->memchunk.length = 0;
+ }
+ position = u->write_count - pa_usec_to_bytes(u->delay, &u->sink->sample_spec);
+
+ now = pa_rtclock_now();
+ estimated = pa_bytes_to_usec(position, &u->sink->sample_spec);
+ pa_smoother_put(u->smoother, now, estimated);
+
+ if ((u->autonull && !canstream) || (u->oob && canstream && on_timeout)) {
+ /* Sleep until next packet transmission */
intvl = u->start + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec);
pa_rtpoll_set_timer_absolute(u->rtpoll, intvl);
- pollfd->revents = 0;
- pollfd->events = 0;
+ } else if (!u->oob) {
+ if (u->memchunk.length > 0) {
+ pollfd->events = POLLOUT;
+ pollfd->revents = 0;
+ } else {
+ intvl = u->start + pa_bytes_to_usec(u->write_count, &u->sink->sample_spec);
+ pa_rtpoll_set_timer_absolute(u->rtpoll, intvl);
+ pollfd->revents = 0;
+ pollfd->events = 0;
+ }
}
}
}
@@ -553,6 +695,7 @@ static pa_card *raop_create_card(pa_module *m, pa_device_port *port, pa_card_pro
pa_sink* pa_raop_sink_new(pa_module *m, pa_modargs *ma, const char *driver) {
struct userdata *u = NULL;
pa_sample_spec ss;
+ pa_channel_map map;
char *thread_name = NULL;
const char *server, *protocol, *encryption, *codec;
const char /* *username, */ *password;
@@ -566,8 +709,10 @@ pa_sink* pa_raop_sink_new(pa_module *m, pa_modargs *ma, const char *driver) {
pa_assert(ma);
ss = m->core->default_sample_spec;
- if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
- pa_log("Failed to parse sample specification");
+ map = m->core->default_channel_map;
+
+ if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
+ pa_log("Invalid sample format specification or channel map");
goto fail;
}
@@ -588,6 +733,15 @@ pa_sink* pa_raop_sink_new(pa_module *m, pa_modargs *ma, const char *driver) {
u->rtpoll = pa_rtpoll_new();
u->rtpoll_item = NULL;
u->latency = RAOP_DEFAULT_LATENCY;
+ u->autoreconnect = false;
+ u->server = pa_xstrdup(server);
+
+ if (pa_modargs_get_value_boolean(ma, "autoreconnect", &u->autoreconnect) < 0) {
+ pa_log("Failed to parse autoreconnect argument");
+ goto fail;
+ }
+ /* Linked for now, potentially ready for additional parameter */
+ u->autonull = u->autoreconnect;
if (pa_modargs_get_value_u32(ma, "latency_msec", &u->latency) < 0) {
pa_log("Failed to parse latency_msec argument");
@@ -667,6 +821,7 @@ pa_sink* pa_raop_sink_new(pa_module *m, pa_modargs *ma, const char *driver) {
}
pa_sink_new_data_set_sample_spec(&data, &ss);
+ pa_sink_new_data_set_channel_map(&data, &map);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_STRING, server);
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "music");
@@ -718,7 +873,7 @@ pa_sink* pa_raop_sink_new(pa_module *m, pa_modargs *ma, const char *driver) {
pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
pa_sink_set_rtpoll(u->sink, u->rtpoll);
- u->raop = pa_raop_client_new(u->core, server, u->protocol, u->encryption, u->codec);
+ u->raop = pa_raop_client_new(u->core, server, u->protocol, u->encryption, u->codec, u->autoreconnect);
if (!(u->raop)) {
pa_log("Failed to create RAOP client object");
@@ -729,6 +884,7 @@ pa_sink* pa_raop_sink_new(pa_module *m, pa_modargs *ma, const char *driver) {
pa_raop_client_get_frames_per_block(u->raop, &u->block_size);
u->block_size *= pa_frame_size(&ss);
pa_sink_set_max_request(u->sink, u->block_size);
+ u->block_usec = pa_bytes_to_usec(u->block_size, &u->sink->sample_spec);
pa_raop_client_set_state_callback(u->raop, raop_state_cb, u);
@@ -794,6 +950,8 @@ static void userdata_free(struct userdata *u) {
if (u->card)
pa_card_free(u->card);
+ if (u->server)
+ pa_xfree(u->server);
pa_xfree(u);
}
diff --git a/src/modules/rtp/meson.build b/src/modules/rtp/meson.build
index c3efde6..119cf08 100644
--- a/src/modules/rtp/meson.build
+++ b/src/modules/rtp/meson.build
@@ -1,5 +1,5 @@
librtp_sources = [
- 'rtp.c',
+ 'rtp-common.c',
'sdp.c',
'sap.c',
'rtsp_client.c',
@@ -14,13 +14,19 @@ librtp_headers = [
'headerlist.h',
]
+if have_gstreamer
+ librtp_sources += 'rtp-gstreamer.c'
+else
+ librtp_sources += 'rtp-native.c'
+endif
+
librtp = shared_library('rtp',
librtp_sources,
librtp_headers,
c_args : [pa_c_args, server_c_args],
link_args : [nodelete_link_args],
include_directories : [configinc, topinc],
- dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep],
+ dependencies : [libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libatomic_ops_dep, gst_dep, gstapp_dep, gstrtp_dep, gio_dep],
install : true,
install_rpath : privlibdir,
install_dir : modlibexecdir,
diff --git a/src/modules/rtp/module-rtp-recv.c b/src/modules/rtp/module-rtp-recv.c
index 79e712d..a9b42bb 100644
--- a/src/modules/rtp/module-rtp-recv.c
+++ b/src/modules/rtp/module-rtp-recv.c
@@ -90,12 +90,11 @@ struct session {
pa_memblockq *memblockq;
bool first_packet;
- uint32_t ssrc;
uint32_t offset;
struct pa_sdp_info sdp_info;
- pa_rtp_context rtp_context;
+ pa_rtp_context *rtp_context;
pa_rtpoll_item *rtpoll_item;
@@ -205,12 +204,13 @@ static void sink_input_suspend_within_thread(pa_sink_input* i, bool b) {
/* Called from I/O thread context */
static int rtpoll_work_cb(pa_rtpoll_item *i) {
pa_memchunk chunk;
+ uint32_t timestamp;
int64_t k, j, delta;
struct timeval now = { 0, 0 };
struct session *s;
struct pollfd *p;
- pa_assert_se(s = pa_rtpoll_item_get_userdata(i));
+ pa_assert_se(s = pa_rtpoll_item_get_work_userdata(i));
p = pa_rtpoll_item_get_pollfd(i, NULL);
@@ -224,40 +224,30 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
p->revents = 0;
- if (pa_rtp_recv(&s->rtp_context, &chunk, s->userdata->module->core->mempool, &now) < 0)
+ if (pa_rtp_recv(s->rtp_context, &chunk, s->userdata->module->core->mempool, &timestamp, &now) < 0)
return 0;
- if (s->sdp_info.payload != s->rtp_context.payload ||
- !PA_SINK_IS_OPENED(s->sink_input->sink->thread_info.state)) {
+ if (!PA_SINK_IS_OPENED(s->sink_input->sink->thread_info.state)) {
pa_memblock_unref(chunk.memblock);
return 0;
}
if (!s->first_packet) {
s->first_packet = true;
-
- s->ssrc = s->rtp_context.ssrc;
- s->offset = s->rtp_context.timestamp;
-
- if (s->ssrc == s->userdata->module->core->cookie)
- pa_log_warn("Detected RTP packet loop!");
- } else {
- if (s->ssrc != s->rtp_context.ssrc) {
- pa_memblock_unref(chunk.memblock);
- return 0;
- }
+ s->offset = timestamp;
}
/* Check whether there was a timestamp overflow */
- k = (int64_t) s->rtp_context.timestamp - (int64_t) s->offset;
- j = (int64_t) 0x100000000LL - (int64_t) s->offset + (int64_t) s->rtp_context.timestamp;
+ k = (int64_t) timestamp - (int64_t) s->offset;
+ j = (int64_t) 0x100000000LL - (int64_t) s->offset + (int64_t) timestamp;
if ((k < 0 ? -k : k) < (j < 0 ? -j : j))
delta = k;
else
delta = j;
- pa_memblockq_seek(s->memblockq, delta * (int64_t) s->rtp_context.frame_size, PA_SEEK_RELATIVE, true);
+ pa_memblockq_seek(s->memblockq, delta * (int64_t) pa_rtp_context_get_frame_size(s->rtp_context), PA_SEEK_RELATIVE,
+ true);
if (now.tv_sec == 0) {
PA_ONCE_BEGIN {
@@ -277,7 +267,7 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
pa_memblock_unref(chunk.memblock);
/* The next timestamp we expect */
- s->offset = s->rtp_context.timestamp + (uint32_t) (chunk.length / s->rtp_context.frame_size);
+ s->offset = timestamp + (uint32_t) (chunk.length / pa_rtp_context_get_frame_size(s->rtp_context));
pa_atomic_store(&s->timestamp, (int) now.tv_sec);
@@ -386,21 +376,14 @@ static int rtpoll_work_cb(pa_rtpoll_item *i) {
/* Called from I/O thread context */
static void sink_input_attach(pa_sink_input *i) {
struct session *s;
- struct pollfd *p;
pa_sink_input_assert_ref(i);
pa_assert_se(s = i->userdata);
pa_assert(!s->rtpoll_item);
- s->rtpoll_item = pa_rtpoll_item_new(i->sink->thread_info.rtpoll, PA_RTPOLL_LATE, 1);
-
- p = pa_rtpoll_item_get_pollfd(s->rtpoll_item, NULL);
- p->fd = s->rtp_context.fd;
- p->events = POLLIN;
- p->revents = 0;
+ s->rtpoll_item = pa_rtp_context_get_rtpoll_item(s->rtp_context, i->sink->thread_info.rtpoll);
- pa_rtpoll_item_set_work_callback(s->rtpoll_item, rtpoll_work_cb);
- pa_rtpoll_item_set_userdata(s->rtpoll_item, s);
+ pa_rtpoll_item_set_work_callback(s->rtpoll_item, rtpoll_work_cb, s);
}
/* Called from I/O thread context */
@@ -585,7 +568,8 @@ static struct session *session_new(struct userdata *u, const pa_sdp_info *sdp_in
pa_memblock_unref(silence.memblock);
- pa_rtp_context_init_recv(&s->rtp_context, fd, pa_frame_size(&s->sdp_info.sample_spec));
+ if (!(s->rtp_context = pa_rtp_context_new_recv(fd, sdp_info->payload, &s->sdp_info.sample_spec)))
+ goto fail;
pa_hashmap_put(s->userdata->by_origin, s->sdp_info.origin, s);
u->n_sessions++;
@@ -620,7 +604,7 @@ static void session_free(struct session *s) {
pa_memblockq_free(s->memblockq);
pa_sdp_info_destroy(&s->sdp_info);
- pa_rtp_context_destroy(&s->rtp_context);
+ pa_rtp_context_free(s->rtp_context);
pa_xfree(s);
}
diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c
index fbaf644..5a4c6fc 100644
--- a/src/modules/rtp/module-rtp-send.c
+++ b/src/modules/rtp/module-rtp-send.c
@@ -107,9 +107,8 @@ struct userdata {
pa_source_output *source_output;
pa_memblockq *memblockq;
- pa_rtp_context rtp_context;
+ pa_rtp_context *rtp_context;
pa_sap_context sap_context;
- size_t mtu;
pa_time_event *sap_event;
@@ -144,7 +143,7 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk)
return;
}
- pa_rtp_send(&u->rtp_context, u->mtu, u->memblockq);
+ pa_rtp_send(u->rtp_context, u->memblockq);
}
static pa_source_output_flags_t get_dont_inhibit_auto_suspend_flag(pa_source *source,
@@ -159,7 +158,7 @@ static pa_source_output_flags_t get_dont_inhibit_auto_suspend_flag(pa_source *so
return PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND;
case INHIBIT_AUTO_SUSPEND_ONLY_WITH_NON_MONITOR_SOURCES:
- return source->monitor_of ? 0 : PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND;
+ return source->monitor_of ? PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND : 0;
}
pa_assert_not_reached();
@@ -466,8 +465,6 @@ int pa__init(pa_module*m) {
0,
NULL);
- u->mtu = mtu;
-
k = sizeof(sa_dst);
pa_assert_se((r = getsockname(fd, (struct sockaddr*) &sa_dst, &k)) >= 0);
@@ -491,10 +488,12 @@ int pa__init(pa_module*m) {
pa_xfree(n);
- pa_rtp_context_init_send(&u->rtp_context, fd, m->core->cookie, payload, pa_frame_size(&ss));
+ if (!(u->rtp_context = pa_rtp_context_new_send(fd, payload, mtu, &ss)))
+ goto fail;
pa_sap_context_init_send(&u->sap_context, sap_fd, p);
- pa_log_info("RTP stream initialized with mtu %u on %s:%u from %s ttl=%u, SSRC=0x%08x, payload=%u, initial sequence #%u", mtu, dst_addr, port, src_addr, ttl, u->rtp_context.ssrc, payload, u->rtp_context.sequence);
+ pa_log_info("RTP stream initialized with mtu %u on %s:%u from %s ttl=%u, payload=%u",
+ mtu, dst_addr, port, src_addr, ttl, payload);
pa_log_info("SDP-Data:\n%s\nEOF", p);
pa_sap_send(&u->sap_context, 0);
@@ -536,7 +535,7 @@ void pa__done(pa_module*m) {
pa_source_output_unref(u->source_output);
}
- pa_rtp_context_destroy(&u->rtp_context);
+ pa_rtp_context_free(u->rtp_context);
pa_sap_send(&u->sap_context, 1);
pa_sap_context_destroy(&u->sap_context);
diff --git a/src/modules/rtp/rtp-common.c b/src/modules/rtp/rtp-common.c
new file mode 100644
index 0000000..65e2c7a
--- /dev/null
+++ b/src/modules/rtp/rtp-common.c
@@ -0,0 +1,97 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2006 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "rtp.h"
+
+#include <pulsecore/core-util.h>
+
+uint8_t pa_rtp_payload_from_sample_spec(const pa_sample_spec *ss) {
+ pa_assert(ss);
+
+ if (ss->format == PA_SAMPLE_S16BE && ss->rate == 44100 && ss->channels == 2)
+ return 10;
+ if (ss->format == PA_SAMPLE_S16BE && ss->rate == 44100 && ss->channels == 1)
+ return 11;
+
+ return 127;
+}
+
+pa_sample_spec *pa_rtp_sample_spec_from_payload(uint8_t payload, pa_sample_spec *ss) {
+ pa_assert(ss);
+
+ switch (payload) {
+ case 10:
+ ss->channels = 2;
+ ss->format = PA_SAMPLE_S16BE;
+ ss->rate = 44100;
+ break;
+
+ case 11:
+ ss->channels = 1;
+ ss->format = PA_SAMPLE_S16BE;
+ ss->rate = 44100;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ return ss;
+}
+
+pa_sample_spec *pa_rtp_sample_spec_fixup(pa_sample_spec * ss) {
+ pa_assert(ss);
+
+ if (!pa_rtp_sample_spec_valid(ss))
+ ss->format = PA_SAMPLE_S16BE;
+
+ pa_assert(pa_rtp_sample_spec_valid(ss));
+ return ss;
+}
+
+int pa_rtp_sample_spec_valid(const pa_sample_spec *ss) {
+ pa_assert(ss);
+
+ if (!pa_sample_spec_valid(ss))
+ return 0;
+
+ return ss->format == PA_SAMPLE_S16BE;
+}
+
+const char* pa_rtp_format_to_string(pa_sample_format_t f) {
+ switch (f) {
+ case PA_SAMPLE_S16BE:
+ return "L16";
+ default:
+ return NULL;
+ }
+}
+
+pa_sample_format_t pa_rtp_string_to_format(const char *s) {
+ pa_assert(s);
+
+ if (pa_streq(s, "L16"))
+ return PA_SAMPLE_S16BE;
+ else
+ return PA_SAMPLE_INVALID;
+}
diff --git a/src/modules/rtp/rtp-gstreamer.c b/src/modules/rtp/rtp-gstreamer.c
new file mode 100644
index 0000000..3ee77cb
--- /dev/null
+++ b/src/modules/rtp/rtp-gstreamer.c
@@ -0,0 +1,524 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2016 Arun Raghavan <mail@arunraghavan.net>
+
+ 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <pulse/timeval.h>
+#include <pulsecore/fdsem.h>
+#include <pulsecore/core-rtclock.h>
+
+#include "rtp.h"
+
+#include <gio/gio.h>
+
+#include <gst/gst.h>
+#include <gst/app/gstappsrc.h>
+#include <gst/app/gstappsink.h>
+#include <gst/rtp/gstrtpbuffer.h>
+
+#define MAKE_ELEMENT_NAMED(v, e, n) \
+ v = gst_element_factory_make(e, n); \
+ if (!v) { \
+ pa_log("Could not create %s element", e); \
+ goto fail; \
+ }
+
+#define MAKE_ELEMENT(v, e) MAKE_ELEMENT_NAMED((v), (e), NULL)
+
+struct pa_rtp_context {
+ pa_fdsem *fdsem;
+ pa_sample_spec ss;
+
+ GstElement *pipeline;
+ GstElement *appsrc;
+ GstElement *appsink;
+
+ uint32_t last_timestamp;
+};
+
+static GstCaps* caps_from_sample_spec(const pa_sample_spec *ss) {
+ if (ss->format != PA_SAMPLE_S16BE)
+ return NULL;
+
+ return gst_caps_new_simple("audio/x-raw",
+ "format", G_TYPE_STRING, "S16BE",
+ "rate", G_TYPE_INT, (int) ss->rate,
+ "channels", G_TYPE_INT, (int) ss->channels,
+ "layout", G_TYPE_STRING, "interleaved",
+ NULL);
+}
+static bool init_send_pipeline(pa_rtp_context *c, int fd, uint8_t payload, size_t mtu, const pa_sample_spec *ss) {
+ GstElement *appsrc = NULL, *pay = NULL, *capsf = NULL, *rtpbin = NULL, *sink = NULL;
+ GstCaps *caps;
+ GSocket *socket;
+ GInetSocketAddress *addr;
+ GInetAddress *iaddr;
+ guint16 port;
+ gchar *addr_str;
+
+ MAKE_ELEMENT(appsrc, "appsrc");
+ MAKE_ELEMENT(pay, "rtpL16pay");
+ MAKE_ELEMENT(capsf, "capsfilter");
+ MAKE_ELEMENT(rtpbin, "rtpbin");
+ MAKE_ELEMENT(sink, "udpsink");
+
+ c->pipeline = gst_pipeline_new(NULL);
+
+ gst_bin_add_many(GST_BIN(c->pipeline), appsrc, pay, capsf, rtpbin, sink, NULL);
+
+ caps = caps_from_sample_spec(ss);
+ if (!caps) {
+ pa_log("Unsupported format to payload");
+ goto fail;
+ }
+
+ socket = g_socket_new_from_fd(fd, NULL);
+ if (!socket) {
+ pa_log("Failed to create socket");
+ goto fail;
+ }
+
+ addr = G_INET_SOCKET_ADDRESS(g_socket_get_remote_address(socket, NULL));
+ iaddr = g_inet_socket_address_get_address(addr);
+ addr_str = g_inet_address_to_string(iaddr);
+ port = g_inet_socket_address_get_port(addr);
+
+ g_object_set(appsrc, "caps", caps, "is-live", TRUE, "blocksize", mtu, "format", 3 /* time */, NULL);
+ g_object_set(pay, "mtu", mtu, NULL);
+ g_object_set(sink, "socket", socket, "host", addr_str, "port", port,
+ "enable-last-sample", FALSE, "sync", FALSE, "loop",
+ g_socket_get_multicast_loopback(socket), "ttl",
+ g_socket_get_ttl(socket), "ttl-mc",
+ g_socket_get_multicast_ttl(socket), "auto-multicast", FALSE,
+ NULL);
+
+ g_free(addr_str);
+ g_object_unref(addr);
+ g_object_unref(socket);
+
+ gst_caps_unref(caps);
+
+ /* Force the payload type that we want */
+ caps = gst_caps_new_simple("application/x-rtp", "payload", G_TYPE_INT, (int) payload, NULL);
+ g_object_set(capsf, "caps", caps, NULL);
+ gst_caps_unref(caps);
+
+ if (!gst_element_link(appsrc, pay) ||
+ !gst_element_link(pay, capsf) ||
+ !gst_element_link_pads(capsf, "src", rtpbin, "send_rtp_sink_0") ||
+ !gst_element_link_pads(rtpbin, "send_rtp_src_0", sink, "sink")) {
+
+ pa_log("Could not set up send pipeline");
+ goto fail;
+ }
+
+ if (gst_element_set_state(c->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+ pa_log("Could not start pipeline");
+ goto fail;
+ }
+
+ c->appsrc = gst_object_ref(appsrc);
+
+ return true;
+
+fail:
+ if (c->pipeline) {
+ gst_object_unref(c->pipeline);
+ } else {
+ /* These weren't yet added to pipeline, so we still have a ref */
+ if (appsrc)
+ gst_object_unref(appsrc);
+ if (pay)
+ gst_object_unref(pay);
+ if (capsf)
+ gst_object_unref(capsf);
+ if (rtpbin)
+ gst_object_unref(rtpbin);
+ if (sink)
+ gst_object_unref(sink);
+ }
+
+ return false;
+}
+
+pa_rtp_context* pa_rtp_context_new_send(int fd, uint8_t payload, size_t mtu, const pa_sample_spec *ss) {
+ pa_rtp_context *c = NULL;
+ GError *error = NULL;
+
+ pa_assert(fd >= 0);
+
+ pa_log_info("Initialising GStreamer RTP backend for send");
+
+ c = pa_xnew0(pa_rtp_context, 1);
+
+ c->ss = *ss;
+
+ if (!gst_init_check(NULL, NULL, &error)) {
+ pa_log_error("Could not initialise GStreamer: %s", error->message);
+ g_error_free(error);
+ goto fail;
+ }
+
+ if (!init_send_pipeline(c, fd, payload, mtu, ss))
+ goto fail;
+
+ return c;
+
+fail:
+ pa_rtp_context_free(c);
+ return NULL;
+}
+
+/* Called from I/O thread context */
+static bool process_bus_messages(pa_rtp_context *c) {
+ GstBus *bus;
+ GstMessage *message;
+ bool ret = true;
+
+ bus = gst_pipeline_get_bus(GST_PIPELINE(c->pipeline));
+
+ while (ret && (message = gst_bus_pop(bus))) {
+ if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
+ GError *error = NULL;
+
+ ret = false;
+
+ gst_message_parse_error(message, &error, NULL);
+ pa_log("Got an error: %s", error->message);
+
+ g_error_free(error);
+ }
+
+ gst_message_unref(message);
+ }
+
+ gst_object_unref(bus);
+
+ return ret;
+}
+
+static void free_buffer(pa_memblock *memblock) {
+ pa_memblock_release(memblock);
+ pa_memblock_unref(memblock);
+}
+
+/* Called from I/O thread context */
+int pa_rtp_send(pa_rtp_context *c, pa_memblockq *q) {
+ pa_memchunk chunk = { 0, };
+ GstBuffer *buf;
+ void *data;
+ bool stop = false;
+ int ret = 0;
+
+ pa_assert(c);
+ pa_assert(q);
+
+ if (!process_bus_messages(c))
+ return -1;
+
+ while (!stop && pa_memblockq_peek(q, &chunk) == 0) {
+ GstClock *clock;
+ GstClockTime timestamp, clock_time;
+
+ clock = gst_element_get_clock(c->pipeline);
+ clock_time = gst_clock_get_time(clock);
+ gst_object_unref(clock);
+
+ timestamp = gst_element_get_base_time(c->pipeline);
+ if (timestamp > clock_time)
+ timestamp -= clock_time;
+ else
+ timestamp = 0;
+
+ pa_assert(chunk.memblock);
+
+ data = pa_memblock_acquire(chunk.memblock);
+
+ buf = gst_buffer_new_wrapped_full(GST_MEMORY_FLAG_READONLY | GST_MEMORY_FLAG_PHYSICALLY_CONTIGUOUS,
+ data, chunk.length, chunk.index, chunk.length, chunk.memblock,
+ (GDestroyNotify) free_buffer);
+
+ GST_BUFFER_PTS(buf) = timestamp;
+
+ if (gst_app_src_push_buffer(GST_APP_SRC(c->appsrc), buf) != GST_FLOW_OK) {
+ pa_log_error("Could not push buffer");
+ stop = true;
+ ret = -1;
+ }
+
+ pa_memblockq_drop(q, chunk.length);
+ }
+
+ return ret;
+}
+
+static GstCaps* rtp_caps_from_sample_spec(const pa_sample_spec *ss) {
+ if (ss->format != PA_SAMPLE_S16BE)
+ return NULL;
+
+ return gst_caps_new_simple("application/x-rtp",
+ "media", G_TYPE_STRING, "audio",
+ "encoding-name", G_TYPE_STRING, "L16",
+ "clock-rate", G_TYPE_INT, (int) ss->rate,
+ "payload", G_TYPE_INT, (int) pa_rtp_payload_from_sample_spec(ss),
+ "layout", G_TYPE_STRING, "interleaved",
+ NULL);
+}
+
+static void on_pad_added(GstElement *element, GstPad *pad, gpointer userdata) {
+ pa_rtp_context *c = (pa_rtp_context *) userdata;
+ GstElement *depay;
+ GstPad *sinkpad;
+ GstPadLinkReturn ret;
+
+ depay = gst_bin_get_by_name(GST_BIN(c->pipeline), "depay");
+ pa_assert(depay);
+
+ sinkpad = gst_element_get_static_pad(depay, "sink");
+
+ ret = gst_pad_link(pad, sinkpad);
+ if (ret != GST_PAD_LINK_OK) {
+ GstBus *bus;
+ GError *error;
+
+ bus = gst_pipeline_get_bus(GST_PIPELINE(c->pipeline));
+ error = g_error_new(GST_CORE_ERROR, GST_CORE_ERROR_PAD, "Could not link rtpbin to depayloader");
+ gst_bus_post(bus, gst_message_new_error(GST_OBJECT(c->pipeline), error, NULL));
+
+ /* Actually cause the I/O thread to wake up and process the error */
+ pa_fdsem_post(c->fdsem);
+
+ g_error_free(error);
+ gst_object_unref(bus);
+ }
+
+ gst_object_unref(sinkpad);
+ gst_object_unref(depay);
+}
+
+static bool init_receive_pipeline(pa_rtp_context *c, int fd, const pa_sample_spec *ss) {
+ GstElement *udpsrc = NULL, *rtpbin = NULL, *depay = NULL, *appsink = NULL;
+ GstCaps *caps;
+ GSocket *socket;
+ GError *error = NULL;
+
+ MAKE_ELEMENT(udpsrc, "udpsrc");
+ MAKE_ELEMENT(rtpbin, "rtpbin");
+ MAKE_ELEMENT_NAMED(depay, "rtpL16depay", "depay");
+ MAKE_ELEMENT(appsink, "appsink");
+
+ c->pipeline = gst_pipeline_new(NULL);
+
+ gst_bin_add_many(GST_BIN(c->pipeline), udpsrc, rtpbin, depay, appsink, NULL);
+
+ socket = g_socket_new_from_fd(fd, &error);
+ if (error) {
+ pa_log("Could not create socket: %s", error->message);
+ g_error_free(error);
+ goto fail;
+ }
+
+ caps = rtp_caps_from_sample_spec(ss);
+ if (!caps) {
+ pa_log("Unsupported format to payload");
+ goto fail;
+ }
+
+ g_object_set(udpsrc, "socket", socket, "caps", caps, "auto-multicast" /* caller handles this */, FALSE, NULL);
+ g_object_set(rtpbin, "latency", 0, "buffer-mode", 0 /* none */, NULL);
+ g_object_set(appsink, "sync", FALSE, "enable-last-sample", FALSE, NULL);
+
+ gst_caps_unref(caps);
+ g_object_unref(socket);
+
+ if (!gst_element_link_pads(udpsrc, "src", rtpbin, "recv_rtp_sink_0") ||
+ !gst_element_link(depay, appsink)) {
+
+ pa_log("Could not set up receive pipeline");
+ goto fail;
+ }
+
+ g_signal_connect(G_OBJECT(rtpbin), "pad-added", G_CALLBACK(on_pad_added), c);
+
+ if (gst_element_set_state(c->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
+ pa_log("Could not start pipeline");
+ goto fail;
+ }
+
+ c->appsink = gst_object_ref(appsink);
+
+ return true;
+
+fail:
+ if (c->pipeline) {
+ gst_object_unref(c->pipeline);
+ } else {
+ /* These weren't yet added to pipeline, so we still have a ref */
+ if (udpsrc)
+ gst_object_unref(udpsrc);
+ if (depay)
+ gst_object_unref(depay);
+ if (rtpbin)
+ gst_object_unref(rtpbin);
+ if (appsink)
+ gst_object_unref(appsink);
+ }
+
+ return false;
+}
+
+/* Called from the GStreamer streaming thread */
+static void appsink_eos(GstAppSink *appsink, gpointer userdata) {
+ pa_rtp_context *c = (pa_rtp_context *) userdata;
+
+ pa_fdsem_post(c->fdsem);
+}
+
+/* Called from the GStreamer streaming thread */
+static GstFlowReturn appsink_new_sample(GstAppSink *appsink, gpointer userdata) {
+ pa_rtp_context *c = (pa_rtp_context *) userdata;
+
+ pa_fdsem_post(c->fdsem);
+
+ return GST_FLOW_OK;
+}
+
+pa_rtp_context* pa_rtp_context_new_recv(int fd, uint8_t payload, const pa_sample_spec *ss) {
+ pa_rtp_context *c = NULL;
+ GstAppSinkCallbacks callbacks = { 0, };
+ GError *error = NULL;
+
+ pa_assert(fd >= 0);
+
+ pa_log_info("Initialising GStreamer RTP backend for receive");
+
+ c = pa_xnew0(pa_rtp_context, 1);
+
+ c->fdsem = pa_fdsem_new();
+ c->ss = *ss;
+
+ if (!gst_init_check(NULL, NULL, &error)) {
+ pa_log_error("Could not initialise GStreamer: %s", error->message);
+ g_error_free(error);
+ goto fail;
+ }
+
+ if (!init_receive_pipeline(c, fd, ss))
+ goto fail;
+
+ callbacks.eos = appsink_eos;
+ callbacks.new_sample = appsink_new_sample;
+ gst_app_sink_set_callbacks(GST_APP_SINK(c->appsink), &callbacks, c, NULL);
+
+ return c;
+
+fail:
+ pa_rtp_context_free(c);
+ return NULL;
+}
+
+/* Called from I/O thread context */
+int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, uint32_t *rtp_tstamp, struct timeval *tstamp) {
+ GstSample *sample = NULL;
+ GstBuffer *buf;
+ GstMapInfo info;
+ void *data;
+
+ if (!process_bus_messages(c))
+ goto fail;
+
+ sample = gst_app_sink_pull_sample(GST_APP_SINK(c->appsink));
+ if (!sample) {
+ pa_log_warn("Could not get any more data");
+ goto fail;
+ }
+
+ buf = gst_sample_get_buffer(sample);
+
+ if (GST_BUFFER_IS_DISCONT(buf))
+ pa_log_info("Discontinuity detected, possibly lost some packets");
+
+ if (!gst_buffer_map(buf, &info, GST_MAP_READ))
+ goto fail;
+
+ pa_assert(pa_mempool_block_size_max(pool) >= info.size);
+
+ chunk->memblock = pa_memblock_new(pool, info.size);
+ chunk->index = 0;
+ chunk->length = info.size;
+
+ data = pa_memblock_acquire_chunk(chunk);
+ /* TODO: we could probably just provide an allocator and avoid a memcpy */
+ memcpy(data, info.data, info.size);
+ pa_memblock_release(chunk->memblock);
+
+ /* When buffer-mode = none, the buffer PTS is the RTP timestamp, converted
+ * to time units (instead of clock-rate units as is in the header) and
+ * wraparound-corrected, and the DTS is the pipeline clock timestamp from
+ * when the buffer was acquired at the source (this is actually the running
+ * time which is why we need to add base time). */
+ *rtp_tstamp = gst_util_uint64_scale_int(GST_BUFFER_PTS(buf), c->ss.rate, GST_SECOND) & 0xFFFFFFFFU;
+ pa_timeval_rtstore(tstamp, (GST_BUFFER_DTS(buf) + gst_element_get_base_time(c->pipeline)) / GST_USECOND, false);
+
+ gst_buffer_unmap(buf, &info);
+ gst_sample_unref(sample);
+
+ return 0;
+
+fail:
+ if (sample)
+ gst_sample_unref(sample);
+
+ if (chunk->memblock)
+ pa_memblock_unref(chunk->memblock);
+
+ return -1;
+}
+
+void pa_rtp_context_free(pa_rtp_context *c) {
+ pa_assert(c);
+
+ if (c->appsrc) {
+ gst_app_src_end_of_stream(GST_APP_SRC(c->appsrc));
+ gst_object_unref(c->appsrc);
+ }
+
+ if (c->appsink)
+ gst_object_unref(c->appsink);
+
+ if (c->pipeline) {
+ gst_element_set_state(c->pipeline, GST_STATE_NULL);
+ gst_object_unref(c->pipeline);
+ }
+
+ if (c->fdsem)
+ pa_fdsem_free(c->fdsem);
+
+ pa_xfree(c);
+}
+
+pa_rtpoll_item* pa_rtp_context_get_rtpoll_item(pa_rtp_context *c, pa_rtpoll *rtpoll) {
+ return pa_rtpoll_item_new_fdsem(rtpoll, PA_RTPOLL_LATE, c->fdsem);
+}
+
+size_t pa_rtp_context_get_frame_size(pa_rtp_context *c) {
+ return pa_frame_size(&c->ss);
+}
diff --git a/src/modules/rtp/rtp.c b/src/modules/rtp/rtp-native.c
index 5ab80e7..01e668c 100644
--- a/src/modules/rtp/rtp.c
+++ b/src/modules/rtp/rtp-native.c
@@ -40,19 +40,40 @@
#include <pulsecore/macro.h>
#include <pulsecore/core-util.h>
#include <pulsecore/arpa-inet.h>
+#include <pulsecore/poll.h>
#include "rtp.h"
-pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssrc, uint8_t payload, size_t frame_size) {
- pa_assert(c);
+typedef struct pa_rtp_context {
+ int fd;
+ uint16_t sequence;
+ uint32_t timestamp;
+ uint32_t ssrc;
+ uint8_t payload;
+ size_t frame_size;
+ size_t mtu;
+
+ uint8_t *recv_buf;
+ size_t recv_buf_size;
+ pa_memchunk memchunk;
+} pa_rtp_context;
+
+pa_rtp_context* pa_rtp_context_new_send(int fd, uint8_t payload, size_t mtu, const pa_sample_spec *ss) {
+ pa_rtp_context *c;
+
pa_assert(fd >= 0);
+ pa_log_info("Initialising native RTP backend for send");
+
+ c = pa_xnew0(pa_rtp_context, 1);
+
c->fd = fd;
c->sequence = (uint16_t) (rand()*rand());
c->timestamp = 0;
- c->ssrc = ssrc ? ssrc : (uint32_t) (rand()*rand());
+ c->ssrc = (uint32_t) (rand()*rand());
c->payload = (uint8_t) (payload & 127U);
- c->frame_size = frame_size;
+ c->frame_size = pa_frame_size(ss);
+ c->mtu = mtu;
c->recv_buf = NULL;
c->recv_buf_size = 0;
@@ -63,17 +84,16 @@ pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssr
#define MAX_IOVECS 16
-int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
+int pa_rtp_send(pa_rtp_context *c, pa_memblockq *q) {
struct iovec iov[MAX_IOVECS];
pa_memblock* mb[MAX_IOVECS];
int iov_idx = 1;
size_t n = 0;
pa_assert(c);
- pa_assert(size > 0);
pa_assert(q);
- if (pa_memblockq_get_length(q) < size)
+ if (pa_memblockq_get_length(q) < c->mtu)
return 0;
for (;;) {
@@ -84,7 +104,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
if ((r = pa_memblockq_peek(q, &chunk)) >= 0) {
- size_t k = n + chunk.length > size ? size - n : chunk.length;
+ size_t k = n + chunk.length > c->mtu ? c->mtu - n : chunk.length;
pa_assert(chunk.memblock);
@@ -99,7 +119,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
pa_assert(n % c->frame_size == 0);
- if (r < 0 || n >= size || iov_idx >= MAX_IOVECS) {
+ if (r < 0 || n >= c->mtu || iov_idx >= MAX_IOVECS) {
uint32_t header[3];
struct msghdr m;
ssize_t k;
@@ -140,7 +160,7 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
return -1;
}
- if (r < 0 || pa_memblockq_get_length(q) < size)
+ if (r < 0 || pa_memblockq_get_length(q) < c->mtu)
break;
n = 0;
@@ -151,19 +171,25 @@ int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q) {
return 0;
}
-pa_rtp_context* pa_rtp_context_init_recv(pa_rtp_context *c, int fd, size_t frame_size) {
- pa_assert(c);
+pa_rtp_context* pa_rtp_context_new_recv(int fd, uint8_t payload, const pa_sample_spec *ss) {
+ pa_rtp_context *c;
+
+ pa_log_info("Initialising native RTP backend for receive");
+
+ c = pa_xnew0(pa_rtp_context, 1);
c->fd = fd;
- c->frame_size = frame_size;
+ c->payload = payload;
+ c->frame_size = pa_frame_size(ss);
c->recv_buf_size = 2000;
c->recv_buf = pa_xmalloc(c->recv_buf_size);
pa_memchunk_reset(&c->memchunk);
+
return c;
}
-int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct timeval *tstamp) {
+int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, uint32_t *rtp_tstamp, struct timeval *tstamp) {
int size;
size_t audio_length;
size_t metadata_length;
@@ -171,6 +197,8 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct
struct cmsghdr *cm;
struct iovec iov;
uint32_t header;
+ uint32_t ssrc;
+ uint8_t payload;
unsigned cc;
ssize_t r;
uint8_t aux[1024];
@@ -246,12 +274,12 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct
}
memcpy(&header, iov.iov_base, sizeof(uint32_t));
- memcpy(&c->timestamp, (uint8_t*) iov.iov_base + 4, sizeof(uint32_t));
- memcpy(&c->ssrc, (uint8_t*) iov.iov_base + 8, sizeof(uint32_t));
+ memcpy(rtp_tstamp, (uint8_t*) iov.iov_base + 4, sizeof(uint32_t));
+ memcpy(&ssrc, (uint8_t*) iov.iov_base + 8, sizeof(uint32_t));
header = ntohl(header);
- c->timestamp = ntohl(c->timestamp);
- c->ssrc = ntohl(c->ssrc);
+ *rtp_tstamp = ntohl(*rtp_tstamp);
+ ssrc = ntohl(c->ssrc);
if ((header >> 30) != 2) {
pa_log_warn("Unsupported RTP version.");
@@ -268,12 +296,22 @@ int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct
goto fail;
}
+ if (ssrc != c->ssrc) {
+ pa_log_debug("Got unexpected SSRC");
+ goto fail;
+ }
+
cc = (header >> 24) & 0xF;
- c->payload = (uint8_t) ((header >> 16) & 127U);
+ payload = (uint8_t) ((header >> 16) & 127U);
c->sequence = (uint16_t) (header & 0xFFFFU);
metadata_length = 12 + cc * 4;
+ if (payload != c->payload) {
+ pa_log_debug("Got unexpected payload: %u", payload);
+ goto fail;
+ }
+
if (metadata_length > (unsigned) size) {
pa_log_warn("RTP packet too short. (CSRC)");
goto fail;
@@ -335,80 +373,7 @@ fail:
return -1;
}
-uint8_t pa_rtp_payload_from_sample_spec(const pa_sample_spec *ss) {
- pa_assert(ss);
-
- if (ss->format == PA_SAMPLE_ULAW && ss->rate == 8000 && ss->channels == 1)
- return 0;
- if (ss->format == PA_SAMPLE_ALAW && ss->rate == 8000 && ss->channels == 1)
- return 8;
- if (ss->format == PA_SAMPLE_S16BE && ss->rate == 44100 && ss->channels == 2)
- return 10;
- if (ss->format == PA_SAMPLE_S16BE && ss->rate == 44100 && ss->channels == 1)
- return 11;
-
- return 127;
-}
-
-pa_sample_spec *pa_rtp_sample_spec_from_payload(uint8_t payload, pa_sample_spec *ss) {
- pa_assert(ss);
-
- switch (payload) {
- case 0:
- ss->channels = 1;
- ss->format = PA_SAMPLE_ULAW;
- ss->rate = 8000;
- break;
-
- case 8:
- ss->channels = 1;
- ss->format = PA_SAMPLE_ALAW;
- ss->rate = 8000;
- break;
-
- case 10:
- ss->channels = 2;
- ss->format = PA_SAMPLE_S16BE;
- ss->rate = 44100;
- break;
-
- case 11:
- ss->channels = 1;
- ss->format = PA_SAMPLE_S16BE;
- ss->rate = 44100;
- break;
-
- default:
- return NULL;
- }
-
- return ss;
-}
-
-pa_sample_spec *pa_rtp_sample_spec_fixup(pa_sample_spec * ss) {
- pa_assert(ss);
-
- if (!pa_rtp_sample_spec_valid(ss))
- ss->format = PA_SAMPLE_S16BE;
-
- pa_assert(pa_rtp_sample_spec_valid(ss));
- return ss;
-}
-
-int pa_rtp_sample_spec_valid(const pa_sample_spec *ss) {
- pa_assert(ss);
-
- if (!pa_sample_spec_valid(ss))
- return 0;
-
- return
- ss->format == PA_SAMPLE_U8 ||
- ss->format == PA_SAMPLE_ALAW ||
- ss->format == PA_SAMPLE_ULAW ||
- ss->format == PA_SAMPLE_S16BE;
-}
-
-void pa_rtp_context_destroy(pa_rtp_context *c) {
+void pa_rtp_context_free(pa_rtp_context *c) {
pa_assert(c);
pa_assert_se(pa_close(c->fd) == 0);
@@ -417,36 +382,23 @@ void pa_rtp_context_destroy(pa_rtp_context *c) {
pa_memblock_unref(c->memchunk.memblock);
pa_xfree(c->recv_buf);
- c->recv_buf = NULL;
- c->recv_buf_size = 0;
+ pa_xfree(c);
}
-const char* pa_rtp_format_to_string(pa_sample_format_t f) {
- switch (f) {
- case PA_SAMPLE_S16BE:
- return "L16";
- case PA_SAMPLE_U8:
- return "L8";
- case PA_SAMPLE_ALAW:
- return "PCMA";
- case PA_SAMPLE_ULAW:
- return "PCMU";
- default:
- return NULL;
- }
+size_t pa_rtp_context_get_frame_size(pa_rtp_context *c) {
+ return c->frame_size;
}
-pa_sample_format_t pa_rtp_string_to_format(const char *s) {
- pa_assert(s);
-
- if (pa_streq(s, "L16"))
- return PA_SAMPLE_S16BE;
- else if (pa_streq(s, "L8"))
- return PA_SAMPLE_U8;
- else if (pa_streq(s, "PCMA"))
- return PA_SAMPLE_ALAW;
- else if (pa_streq(s, "PCMU"))
- return PA_SAMPLE_ULAW;
- else
- return PA_SAMPLE_INVALID;
+pa_rtpoll_item* pa_rtp_context_get_rtpoll_item(pa_rtp_context *c, pa_rtpoll *rtpoll) {
+ pa_rtpoll_item *item;
+ struct pollfd *p;
+
+ item = pa_rtpoll_item_new(rtpoll, PA_RTPOLL_LATE, 1);
+
+ p = pa_rtpoll_item_get_pollfd(item, NULL);
+ p->fd = c->fd;
+ p->events = POLLIN;
+ p->revents = 0;
+
+ return item;
}
diff --git a/src/modules/rtp/rtp.h b/src/modules/rtp/rtp.h
index 0b877d5..372df75 100644
--- a/src/modules/rtp/rtp.h
+++ b/src/modules/rtp/rtp.h
@@ -25,30 +25,24 @@
#include <sys/types.h>
#include <pulsecore/memblockq.h>
#include <pulsecore/memchunk.h>
+#include <pulsecore/rtpoll.h>
-typedef struct pa_rtp_context {
- int fd;
- uint16_t sequence;
- uint32_t timestamp;
- uint32_t ssrc;
- uint8_t payload;
- size_t frame_size;
+typedef struct pa_rtp_context pa_rtp_context;
- uint8_t *recv_buf;
- size_t recv_buf_size;
- pa_memchunk memchunk;
-} pa_rtp_context;
-
-pa_rtp_context* pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint32_t ssrc, uint8_t payload, size_t frame_size);
+int pa_rtp_context_init_send(pa_rtp_context *c, int fd, uint8_t payload, size_t mtu, size_t frame_size);
+pa_rtp_context* pa_rtp_context_new_send(int fd, uint8_t payload, size_t mtu, const pa_sample_spec *ss);
/* If the memblockq doesn't have a silence memchunk set, then the caller must
* guarantee that the current read index doesn't point to a hole. */
-int pa_rtp_send(pa_rtp_context *c, size_t size, pa_memblockq *q);
+int pa_rtp_send(pa_rtp_context *c, pa_memblockq *q);
+
+pa_rtp_context* pa_rtp_context_new_recv(int fd, uint8_t payload, const pa_sample_spec *ss);
+int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, uint32_t *rtp_tstamp, struct timeval *tstamp);
-pa_rtp_context* pa_rtp_context_init_recv(pa_rtp_context *c, int fd, size_t frame_size);
-int pa_rtp_recv(pa_rtp_context *c, pa_memchunk *chunk, pa_mempool *pool, struct timeval *tstamp);
+void pa_rtp_context_free(pa_rtp_context *c);
-void pa_rtp_context_destroy(pa_rtp_context *c);
+size_t pa_rtp_context_get_frame_size(pa_rtp_context *c);
+pa_rtpoll_item* pa_rtp_context_get_rtpoll_item(pa_rtp_context *c, pa_rtpoll *rtpoll);
pa_sample_spec* pa_rtp_sample_spec_fixup(pa_sample_spec *ss);
int pa_rtp_sample_spec_valid(const pa_sample_spec *ss);
diff --git a/src/modules/rtp/rtsp_client.c b/src/modules/rtp/rtsp_client.c
index 34210f9..9fd386a 100644
--- a/src/modules/rtp/rtsp_client.c
+++ b/src/modules/rtp/rtsp_client.c
@@ -27,6 +27,8 @@
#include <unistd.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
+#include <pulse/rtclock.h>
+#include <pulse/timeval.h>
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
@@ -42,9 +44,12 @@
#include <pulsecore/ioline.h>
#include <pulsecore/arpa-inet.h>
#include <pulsecore/random.h>
+#include <pulsecore/core-rtclock.h>
#include "rtsp_client.h"
+#define RECONNECT_INTERVAL (5 * PA_USEC_PER_SEC)
+
struct pa_rtsp_client {
pa_mainloop_api *mainloop;
char *hostname;
@@ -73,9 +78,11 @@ struct pa_rtsp_client {
uint32_t cseq;
char *session;
char *transport;
+ pa_time_event *reconnect_event;
+ bool autoreconnect;
};
-pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent) {
+pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent, bool autoreconnect) {
pa_rtsp_client *c;
pa_assert(mainloop);
@@ -93,12 +100,23 @@ pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostna
else
c->useragent = "PulseAudio RTSP Client";
+ c->autoreconnect = autoreconnect;
return c;
}
+static void free_events(pa_rtsp_client *c) {
+ pa_assert(c);
+
+ if (c->reconnect_event) {
+ c->mainloop->time_free(c->reconnect_event);
+ c->reconnect_event = NULL;
+ }
+}
+
void pa_rtsp_client_free(pa_rtsp_client *c) {
pa_assert(c);
+ free_events(c);
if (c->sc)
pa_socket_client_unref(c->sc);
@@ -293,6 +311,13 @@ static void line_callback(pa_ioline *line, const char *s, void *userdata) {
pa_xfree(s2);
}
+static void reconnect_cb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
+ if (userdata) {
+ pa_rtsp_client *c = userdata;
+ pa_rtsp_connect(c);
+ }
+}
+
static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata) {
pa_rtsp_client *c = userdata;
union {
@@ -310,7 +335,18 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
c->sc = NULL;
if (!io) {
- pa_log("Connection failed: %s", pa_cstrerror(errno));
+ if (c->autoreconnect) {
+ struct timeval tv;
+
+ pa_log_warn("Connection to server %s:%d failed: %s - will try later", c->hostname, c->port, pa_cstrerror(errno));
+
+ if (!c->reconnect_event)
+ c->reconnect_event = c->mainloop->time_new(c->mainloop, pa_timeval_rtstore(&tv, pa_rtclock_now() + RECONNECT_INTERVAL, true), reconnect_cb, c);
+ else
+ c->mainloop->time_restart(c->reconnect_event, pa_timeval_rtstore(&tv, pa_rtclock_now() + RECONNECT_INTERVAL, true));
+ } else {
+ pa_log("Connection to server %s:%d failed: %s", c->hostname, c->port, pa_cstrerror(errno));
+ }
return;
}
pa_assert(!c->ioline);
diff --git a/src/modules/rtp/rtsp_client.h b/src/modules/rtp/rtsp_client.h
index 4e031d8..2593085 100644
--- a/src/modules/rtp/rtsp_client.h
+++ b/src/modules/rtp/rtsp_client.h
@@ -54,7 +54,7 @@ typedef enum pa_rtsp_status {
typedef void (*pa_rtsp_cb_t)(pa_rtsp_client *c, pa_rtsp_state_t state, pa_rtsp_status_t code, pa_headerlist *headers, void *userdata);
-pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent);
+pa_rtsp_client* pa_rtsp_client_new(pa_mainloop_api *mainloop, const char *hostname, uint16_t port, const char *useragent, bool autoreconnect);
void pa_rtsp_client_free(pa_rtsp_client *c);
int pa_rtsp_connect(pa_rtsp_client *c);
diff --git a/src/modules/rtp/sdp.c b/src/modules/rtp/sdp.c
index 14953cf..6a2e0c9 100644
--- a/src/modules/rtp/sdp.c
+++ b/src/modules/rtp/sdp.c
@@ -89,15 +89,6 @@ static pa_sample_spec *parse_sdp_sample_spec(pa_sample_spec *ss, char *c) {
if (pa_startswith(c, "L16/")) {
ss->format = PA_SAMPLE_S16BE;
c += 4;
- } else if (pa_startswith(c, "L8/")) {
- ss->format = PA_SAMPLE_U8;
- c += 3;
- } else if (pa_startswith(c, "PCMA/")) {
- ss->format = PA_SAMPLE_ALAW;
- c += 5;
- } else if (pa_startswith(c, "PCMU/")) {
- ss->format = PA_SAMPLE_ULAW;
- c += 5;
} else
return NULL;
diff --git a/src/modules/x11/module-x11-bell.c b/src/modules/x11/module-x11-bell.c
index 0200359..eab1e6c 100644
--- a/src/modules/x11/module-x11-bell.c
+++ b/src/modules/x11/module-x11-bell.c
@@ -44,6 +44,7 @@ static const char* const valid_modargs[] = {
"sink",
"sample",
"display",
+ "xauthority",
NULL
};
@@ -125,6 +126,13 @@ int pa__init(pa_module*m) {
u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
u->x11_client = NULL;
+ if (pa_modargs_get_value(ma, "xauthority", NULL)) {
+ if (setenv("XAUTHORITY", pa_modargs_get_value(ma, "xauthority", NULL), 1)) {
+ pa_log("setenv() for $XAUTHORITY failed");
+ goto fail;
+ }
+ }
+
if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
goto fail;
diff --git a/src/modules/x11/module-x11-cork-request.c b/src/modules/x11/module-x11-cork-request.c
index ab391c6..6b1a86b 100644
--- a/src/modules/x11/module-x11-cork-request.c
+++ b/src/modules/x11/module-x11-cork-request.c
@@ -46,6 +46,7 @@ PA_MODULE_USAGE("display=<X11 display>");
static const char* const valid_modargs[] = {
"display",
+ "xauthority",
NULL
};
@@ -128,6 +129,13 @@ int pa__init(pa_module *m) {
m->userdata = u = pa_xnew0(struct userdata, 1);
u->module = m;
+ if (pa_modargs_get_value(ma, "xauthority", NULL)) {
+ if (setenv("XAUTHORITY", pa_modargs_get_value(ma, "xauthority", NULL), 1)) {
+ pa_log("setenv() for $XAUTHORITY failed");
+ goto fail;
+ }
+ }
+
if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
goto fail;
diff --git a/src/modules/x11/module-x11-publish.c b/src/modules/x11/module-x11-publish.c
index e6735ec..68adf15 100644
--- a/src/modules/x11/module-x11-publish.c
+++ b/src/modules/x11/module-x11-publish.c
@@ -56,6 +56,7 @@ static const char* const valid_modargs[] = {
"sink",
"source",
"cookie",
+ "xauthority",
NULL
};
@@ -156,6 +157,13 @@ int pa__init(pa_module*m) {
if (!(u->auth_cookie = pa_auth_cookie_get(m->core, pa_modargs_get_value(ma, "cookie", PA_NATIVE_COOKIE_FILE), true, PA_NATIVE_COOKIE_LENGTH)))
goto fail;
+ if (pa_modargs_get_value(ma, "xauthority", NULL)) {
+ if (setenv("XAUTHORITY", pa_modargs_get_value(ma, "xauthority", NULL), 1)) {
+ pa_log("setenv() for $XAUTHORITY failed");
+ goto fail;
+ }
+ }
+
if (!(u->x11_wrapper = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
goto fail;
diff --git a/src/modules/x11/module-x11-xsmp.c b/src/modules/x11/module-x11-xsmp.c
index 6f80123..459da13 100644
--- a/src/modules/x11/module-x11-xsmp.c
+++ b/src/modules/x11/module-x11-xsmp.c
@@ -46,6 +46,7 @@ static bool ice_in_use = false;
static const char* const valid_modargs[] = {
"session_manager",
"display",
+ "xauthority",
NULL
};
@@ -139,6 +140,13 @@ int pa__init(pa_module*m) {
goto fail;
}
+ if (pa_modargs_get_value(ma, "xauthority", NULL)) {
+ if (setenv("XAUTHORITY", pa_modargs_get_value(ma, "xauthority", NULL), 1)) {
+ pa_log("setenv() for $XAUTHORITY failed");
+ goto fail;
+ }
+ }
+
if (!(u->x11 = pa_x11_wrapper_get(m->core, pa_modargs_get_value(ma, "display", NULL))))
goto fail;
diff --git a/src/pulse/context.c b/src/pulse/context.c
index 180e687..1d1bb9e 100644
--- a/src/pulse/context.c
+++ b/src/pulse/context.c
@@ -274,6 +274,7 @@ static void context_free(pa_context *c) {
pa_proplist_free(c->proplist);
pa_xfree(c->server);
+ pa_xfree(c->error);
pa_xfree(c);
}
diff --git a/src/pulse/gccmacro.h b/src/pulse/gccmacro.h
index e5ba5bd..81729db 100644
--- a/src/pulse/gccmacro.h
+++ b/src/pulse/gccmacro.h
@@ -129,4 +129,42 @@
#endif
#endif
+#ifndef PA_LIKELY
+#ifdef __GNUC__
+#define PA_LIKELY(x) (__builtin_expect(!!(x),1))
+#define PA_UNLIKELY(x) (__builtin_expect(!!(x),0))
+#else
+#define PA_LIKELY(x) (x)
+#define PA_UNLIKELY(x) (x)
+#endif
+#endif
+
+#ifdef __GNUC__
+#define PA_CLAMP(x, low, high) \
+ __extension__ ({ \
+ typeof(x) _x = (x); \
+ typeof(low) _low = (low); \
+ typeof(high) _high = (high); \
+ ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
+ })
+#else
+#define PA_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+#endif
+
+#ifdef __GNUC__
+#define PA_CLAMP_UNLIKELY(x, low, high) \
+ __extension__ ({ \
+ typeof(x) _x = (x); \
+ typeof(low) _low = (low); \
+ typeof(high) _high = (high); \
+ (PA_UNLIKELY(_x > _high) ? _high : (PA_UNLIKELY(_x < _low) ? _low : _x)); \
+ })
+#else
+#define PA_CLAMP_UNLIKELY(x, low, high) (PA_UNLIKELY((x) > (high)) ? (high) : (PA_UNLIKELY((x) < (low)) ? (low) : (x)))
+#endif
+
+/* We don't define a PA_CLAMP_LIKELY here, because it doesn't really
+ * make sense: we cannot know if it is more likely that the value is
+ * lower or greater than the boundaries. */
+
#endif
diff --git a/src/pulse/meson.build b/src/pulse/meson.build
index 00c6867..aaebff5 100644
--- a/src/pulse/meson.build
+++ b/src/pulse/meson.build
@@ -81,14 +81,14 @@ libpulse = shared_library('pulse',
link_args : [nodelete_link_args, versioning_link_args],
install : true,
install_rpath : privlibdir,
- dependencies : [libm_dep, thread_dep, libpulsecommon_dep, dbus_dep, dl_dep, iconv_dep],
+ dependencies : [libm_dep, thread_dep, libpulsecommon_dep, dbus_dep, dl_dep, iconv_dep, libintl_dep],
implicit_include_directories : false)
libpulse_dep = declare_dependency(link_with: libpulse)
-install_data(
+install_headers(
libpulse_headers, 'simple.h',
- install_dir : join_paths(includedir, 'pulse')
+ subdir : 'pulse'
)
libpulse_simple = shared_library('pulse-simple',
diff --git a/src/pulse/stream.h b/src/pulse/stream.h
index 7913f7f..f9b52d4 100644
--- a/src/pulse/stream.h
+++ b/src/pulse/stream.h
@@ -414,7 +414,7 @@ int pa_stream_is_corked(const pa_stream *s);
* Returns zero on success. */
int pa_stream_connect_playback(
pa_stream *s /**< The stream to connect to a sink */,
- const char *dev /**< Name of the sink to connect to, or NULL for default */ ,
+ const char *dev /**< Name of the sink to connect to, or NULL to let the server decide */ ,
const pa_buffer_attr *attr /**< Buffering attributes, or NULL for default */,
pa_stream_flags_t flags /**< Additional flags, or 0 for default */,
const pa_cvolume *volume /**< Initial volume, or NULL for default */,
@@ -423,7 +423,7 @@ int pa_stream_connect_playback(
/** Connect the stream to a source. Returns zero on success. */
int pa_stream_connect_record(
pa_stream *s /**< The stream to connect to a source */ ,
- const char *dev /**< Name of the source to connect to, or NULL for default */,
+ const char *dev /**< Name of the source to connect to, or NULL to let the server decide */,
const pa_buffer_attr *attr /**< Buffer attributes, or NULL for default */,
pa_stream_flags_t flags /**< Additional flags, or 0 for default */);
diff --git a/src/pulse/version.h b/src/pulse/version.h
index cac3638..c01760a 100644
--- a/src/pulse/version.h
+++ b/src/pulse/version.h
@@ -33,7 +33,7 @@ PA_C_DECL_BEGIN
/** Return the version of the header files. Keep in mind that this is
a macro and not a function, so it is impossible to get the pointer of
it. */
-#define pa_get_headers_version() ("13.0.0")
+#define pa_get_headers_version() ("13.99.0")
/** Return the version of the library the current application is
* linked to. */
@@ -53,7 +53,7 @@ const char* pa_get_library_version(void);
#define PA_MAJOR 13
/** The minor version of PA. \since 0.9.15 */
-#define PA_MINOR 0
+#define PA_MINOR 99
/** The micro version of PA (will always be 0 from v1.0 onwards). \since 0.9.15 */
#define PA_MICRO 0
diff --git a/src/pulsecore/atomic.h b/src/pulsecore/atomic.h
index a82ca83..e5c1401 100644
--- a/src/pulsecore/atomic.h
+++ b/src/pulsecore/atomic.h
@@ -117,7 +117,7 @@ static inline void* pa_atomic_ptr_load(const pa_atomic_ptr_t *a) {
}
static inline void pa_atomic_ptr_store(pa_atomic_ptr_t *a, void* p) {
- __atomic_store_n(&a->value, p, __ATOMIC_SEQ_CST);
+ __atomic_store_n(&a->value, (unsigned long) p, __ATOMIC_SEQ_CST);
}
#else
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 270acd8..601b1d1 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -784,12 +784,16 @@ void pa_reset_priority(void) {
#endif
}
+/* Check whenever any substring in v matches the provided regex. */
int pa_match(const char *expr, const char *v) {
#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
int k;
regex_t re;
int r;
+ pa_assert(expr);
+ pa_assert(v);
+
if (regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
errno = EINVAL;
return -1;
@@ -814,6 +818,22 @@ int pa_match(const char *expr, const char *v) {
#endif
}
+/* Check whenever the provided regex pattern is valid. */
+bool pa_is_regex_valid(const char *expr) {
+#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H)
+ regex_t re;
+
+ if (expr == NULL || regcomp(&re, expr, REG_NOSUB|REG_EXTENDED) != 0) {
+ return false;
+ }
+
+ regfree(&re);
+ return true;
+#else
+ return false;
+#endif
+}
+
/* Try to parse a boolean string value.*/
int pa_parse_boolean(const char *v) {
pa_assert(v);
@@ -859,7 +879,7 @@ int pa_parse_volume(const char *v, pa_volume_t *volume) {
len = strlen(v);
- if (len >= 64)
+ if (len <= 0 || len >= 64)
return -1;
memcpy(str, v, len + 1);
@@ -1428,7 +1448,7 @@ static int check_ours(const char *p) {
return -errno;
#ifdef HAVE_GETUID
- if (st.st_uid != getuid())
+ if (st.st_uid != getuid() && st.st_uid != 0)
return -EACCES;
#endif
@@ -2873,6 +2893,32 @@ bool pa_str_in_list_spaces(const char *haystack, const char *needle) {
return false;
}
+char* pa_str_strip_suffix(const char *str, const char *suffix) {
+ size_t str_l, suf_l, prefix;
+ char *ret;
+
+ pa_assert(str);
+ pa_assert(suffix);
+
+ str_l = strlen(str);
+ suf_l = strlen(suffix);
+
+ if (str_l < suf_l)
+ return NULL;
+
+ prefix = str_l - suf_l;
+
+ if (!pa_streq(&str[prefix], suffix))
+ return NULL;
+
+ ret = pa_xmalloc(prefix + 1);
+
+ strncpy(ret, str, prefix);
+ ret[prefix] = '\0';
+
+ return ret;
+}
+
char *pa_get_user_name_malloc(void) {
ssize_t k;
char *u;
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index cfb9eb2..9440af9 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -158,6 +158,7 @@ size_t pa_vsnprintf(char *str, size_t size, const char *format, va_list ap);
char *pa_truncate_utf8(char *c, size_t l);
int pa_match(const char *expr, const char *v);
+bool pa_is_regex_valid(const char *expr);
char *pa_getcwd(void);
char *pa_make_path_absolute(const char *p);
@@ -231,6 +232,8 @@ static inline bool pa_safe_streq(const char *a, const char *b) {
bool pa_str_in_list_spaces(const char *needle, const char *haystack);
bool pa_str_in_list(const char *haystack, const char *delimiters, const char *needle);
+char* pa_str_strip_suffix(const char *str, const char *suffix);
+
char *pa_get_host_name_malloc(void);
char *pa_get_user_name_malloc(void);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index e5bb2e4..335f802 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -144,7 +144,8 @@ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t
c->realtime_priority = 5;
c->disable_remixing = false;
c->remixing_use_all_sink_channels = true;
- c->disable_lfe_remixing = true;
+ c->remixing_produce_lfe = false;
+ c->remixing_consume_lfe = false;
c->lfe_crossover_freq = 0;
c->deferred_volume = true;
c->resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 1;
@@ -349,6 +350,10 @@ void pa_core_update_default_sink(pa_core *core) {
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
pa_hook_fire(&core->hooks[PA_CORE_HOOK_DEFAULT_SINK_CHANGED], core->default_sink);
+
+ /* try to move the streams from old_default_sink to the new default_sink conditionally */
+ if (old_default_sink)
+ pa_sink_move_streams_to_default_sink(core, old_default_sink, true);
}
/* a < b -> return -1
@@ -430,6 +435,10 @@ void pa_core_update_default_source(pa_core *core) {
old_default_source ? old_default_source->name : "(unset)", best ? best->name : "(unset)");
pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SERVER | PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
pa_hook_fire(&core->hooks[PA_CORE_HOOK_DEFAULT_SOURCE_CHANGED], core->default_source);
+
+ /* try to move the streams from old_default_source to the new default_source conditionally */
+ if (old_default_source)
+ pa_source_move_streams_to_default_source(core, old_default_source, true);
}
void pa_core_set_exit_idle_time(pa_core *core, int time) {
@@ -519,6 +528,72 @@ void pa_core_rttime_restart(pa_core *c, pa_time_event *e, pa_usec_t usec) {
c->mainloop->time_restart(e, pa_timeval_rtstore(&tv, usec, true));
}
+void pa_core_move_streams_to_newly_available_preferred_sink(pa_core *c, pa_sink *s) {
+ pa_sink_input *si;
+ uint32_t idx;
+
+ pa_assert(c);
+ pa_assert(s);
+
+ PA_IDXSET_FOREACH(si, c->sink_inputs, idx) {
+ if (si->sink == s)
+ continue;
+
+ if (!si->sink)
+ continue;
+
+ /* Skip this sink input if it is connecting a filter sink to
+ * the master */
+ if (si->origin_sink)
+ continue;
+
+ /* It might happen that a stream and a sink are set up at the
+ same time, in which case we want to make sure we don't
+ interfere with that */
+ if (!PA_SINK_INPUT_IS_LINKED(si->state))
+ continue;
+
+ if (pa_safe_streq(si->preferred_sink, s->name))
+ pa_sink_input_move_to(si, s, false);
+ }
+
+}
+
+void pa_core_move_streams_to_newly_available_preferred_source(pa_core *c, pa_source *s) {
+ pa_source_output *so;
+ uint32_t idx;
+
+ pa_assert(c);
+ pa_assert(s);
+
+ PA_IDXSET_FOREACH(so, c->source_outputs, idx) {
+ if (so->source == s)
+ continue;
+
+ if (so->direct_on_input)
+ continue;
+
+ if (!so->source)
+ continue;
+
+ /* Skip this source output if it is connecting a filter source to
+ * the master */
+ if (so->destination_source)
+ continue;
+
+ /* It might happen that a stream and a source are set up at the
+ same time, in which case we want to make sure we don't
+ interfere with that */
+ if (!PA_SOURCE_OUTPUT_IS_LINKED(so->state))
+ continue;
+
+ if (pa_safe_streq(so->preferred_source, s->name))
+ pa_source_output_move_to(so, s, false);
+ }
+
+}
+
+
/* Helper macro to reduce repetition in pa_suspend_cause_to_string().
* Parameters:
* char *p: the current position in the write buffer
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index d03897c..57924b9 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -213,6 +213,7 @@ struct pa_core {
int exit_idle_time, scache_idle_time;
bool flat_volumes:1;
+ bool rescue_streams:1;
bool disallow_module_loading:1;
bool disallow_exit:1;
bool running_as_daemon:1;
@@ -220,7 +221,8 @@ struct pa_core {
bool avoid_resampling:1;
bool disable_remixing:1;
bool remixing_use_all_sink_channels:1;
- bool disable_lfe_remixing:1;
+ bool remixing_produce_lfe:1;
+ bool remixing_consume_lfe:1;
bool deferred_volume:1;
pa_resample_method_t resample_method;
@@ -278,4 +280,8 @@ static const size_t PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE =
* provided buffer. The same buffer is the return value of this function. */
const char *pa_suspend_cause_to_string(pa_suspend_cause_t cause, char buf[PA_SUSPEND_CAUSE_TO_STRING_BUF_SIZE]);
+void pa_core_move_streams_to_newly_available_preferred_sink(pa_core *c, pa_sink *s);
+
+void pa_core_move_streams_to_newly_available_preferred_source(pa_core *c, pa_source *s);
+
#endif
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index fb12772..b104c49 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -100,6 +100,30 @@ void pa_device_port_set_available(pa_device_port *p, pa_available_t status) {
else
pa_core_update_default_source(p->core);
+ if (p->direction == PA_DIRECTION_OUTPUT) {
+ pa_sink *sink;
+
+ sink = pa_device_port_get_sink(p);
+ if (sink && p == sink->active_port) {
+ if (sink->active_port->available == PA_AVAILABLE_NO) {
+ if (p->core->rescue_streams)
+ pa_sink_move_streams_to_default_sink(p->core, sink, false);
+ } else
+ pa_core_move_streams_to_newly_available_preferred_sink(p->core, sink);
+ }
+ } else {
+ pa_source *source;
+
+ source = pa_device_port_get_source(p);
+ if (source && p == source->active_port) {
+ if (source->active_port->available == PA_AVAILABLE_NO) {
+ if (p->core->rescue_streams)
+ pa_source_move_streams_to_default_source(p->core, source, false);
+ } else
+ pa_core_move_streams_to_newly_available_preferred_source(p->core, source);
+ }
+ }
+
pa_subscription_post(p->core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, p->card->index);
pa_hook_fire(&p->core->hooks[PA_CORE_HOOK_PORT_AVAILABLE_CHANGED], p);
}
@@ -224,3 +248,29 @@ pa_device_port *pa_device_port_find_best(pa_hashmap *ports)
return best;
}
+
+pa_sink *pa_device_port_get_sink(pa_device_port *p) {
+ pa_sink *rs = NULL;
+ pa_sink *sink;
+ uint32_t state;
+
+ PA_IDXSET_FOREACH(sink, p->card->sinks, state)
+ if (p == pa_hashmap_get(sink->ports, p->name)) {
+ rs = sink;
+ break;
+ }
+ return rs;
+}
+
+pa_source *pa_device_port_get_source(pa_device_port *p) {
+ pa_source *rs = NULL;
+ pa_source *source;
+ uint32_t state;
+
+ PA_IDXSET_FOREACH(source, p->card->sources, state)
+ if (p == pa_hashmap_get(source->ports, p->name)) {
+ rs = source;
+ break;
+ }
+ return rs;
+}
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index fbdce1a..41198f6 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -87,4 +87,8 @@ void pa_device_port_set_preferred_profile(pa_device_port *p, const char *new_pp)
pa_device_port *pa_device_port_find_best(pa_hashmap *ports);
+pa_sink *pa_device_port_get_sink(pa_device_port *p);
+
+pa_source *pa_device_port_get_source(pa_device_port *p);
+
#endif
diff --git a/src/pulsecore/macro.h b/src/pulsecore/macro.h
index bb15b7f..ec8d31c 100644
--- a/src/pulsecore/macro.h
+++ b/src/pulsecore/macro.h
@@ -34,16 +34,6 @@
#error "Please include config.h before including this file!"
#endif
-#ifndef PA_LIKELY
-#ifdef __GNUC__
-#define PA_LIKELY(x) (__builtin_expect(!!(x),1))
-#define PA_UNLIKELY(x) (__builtin_expect(!!(x),0))
-#else
-#define PA_LIKELY(x) (x)
-#define PA_UNLIKELY(x) (x)
-#endif
-#endif
-
/* Rounds down */
static inline void* PA_ALIGN_PTR(const void *p) {
return (void*) (((size_t) p) & ~(sizeof(void*) - 1));
@@ -100,34 +90,6 @@ static inline size_t PA_ALIGN(size_t l) {
#endif
#ifdef __GNUC__
-#define PA_CLAMP(x, low, high) \
- __extension__ ({ \
- typeof(x) _x = (x); \
- typeof(low) _low = (low); \
- typeof(high) _high = (high); \
- ((_x > _high) ? _high : ((_x < _low) ? _low : _x)); \
- })
-#else
-#define PA_CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
-#endif
-
-#ifdef __GNUC__
-#define PA_CLAMP_UNLIKELY(x, low, high) \
- __extension__ ({ \
- typeof(x) _x = (x); \
- typeof(low) _low = (low); \
- typeof(high) _high = (high); \
- (PA_UNLIKELY(_x > _high) ? _high : (PA_UNLIKELY(_x < _low) ? _low : _x)); \
- })
-#else
-#define PA_CLAMP_UNLIKELY(x, low, high) (PA_UNLIKELY((x) > (high)) ? (high) : (PA_UNLIKELY((x) < (low)) ? (low) : (x)))
-#endif
-
-/* We don't define a PA_CLAMP_LIKELY here, because it doesn't really
- * make sense: we cannot know if it is more likely that the values is
- * lower or greater than the boundaries.*/
-
-#ifdef __GNUC__
#define PA_ROUND_UP(a, b) \
__extension__ ({ \
typeof(a) _a = (a); \
diff --git a/src/pulsecore/meson.build b/src/pulsecore/meson.build
index 19f6b9e..0bd596c 100644
--- a/src/pulsecore/meson.build
+++ b/src/pulsecore/meson.build
@@ -198,7 +198,7 @@ libpulsecore = shared_library('pulsecore-' + pa_version_major_minor,
install_rpath : privlibdir,
install_dir : privlibdir,
link_with : libpulsecore_simd_lib,
- dependencies : [libm_dep, libpulsecommon_dep, libpulse_dep, ltdl_dep, shm_dep, sndfile_dep, database_dep, dbus_dep, libatomic_ops_dep, orc_dep, samplerate_dep, soxr_dep, speex_dep, x11_dep],
+ dependencies : [libm_dep, libpulsecommon_dep, libpulse_dep, ltdl_dep, shm_dep, sndfile_dep, database_dep, dbus_dep, libatomic_ops_dep, orc_dep, samplerate_dep, soxr_dep, speex_dep, x11_dep, libintl_dep],
implicit_include_directories : false)
libpulsecore_dep = declare_dependency(link_with: libpulsecore)
diff --git a/src/pulsecore/resampler.c b/src/pulsecore/resampler.c
index ff9795e..58463f1 100644
--- a/src/pulsecore/resampler.c
+++ b/src/pulsecore/resampler.c
@@ -1099,7 +1099,7 @@ static void setup_remap(const pa_resampler *r, pa_remap_t *m, bool *lfe_remixed)
* right input channel. Something is really wrong in this
* case anyway. */
- } else if (on_lfe(b) && !(r->flags & PA_RESAMPLER_NO_LFE)) {
+ } else if (on_lfe(b) && (r->flags & PA_RESAMPLER_PRODUCE_LFE)) {
/* We are not connected and an LFE. Let's average all
* channels for LFE. */
@@ -1150,7 +1150,7 @@ static void setup_remap(const pa_resampler *r, pa_remap_t *m, bool *lfe_remixed)
m->map_table_f[oc][ic] = (1.f/9.f) / (float) ic_unconnected_center;
ic_unconnected_center_mixed_in = true;
- } else if (on_lfe(a) && !(r->flags & PA_RESAMPLER_NO_LFE))
+ } else if (on_lfe(a) && (r->flags & PA_RESAMPLER_CONSUME_LFE))
m->map_table_f[oc][ic] = .375f / (float) ic_unconnected_lfe;
}
}
diff --git a/src/pulsecore/resampler.h b/src/pulsecore/resampler.h
index 5d3171f..5a264b3 100644
--- a/src/pulsecore/resampler.h
+++ b/src/pulsecore/resampler.h
@@ -68,8 +68,9 @@ typedef enum pa_resample_flags {
PA_RESAMPLER_VARIABLE_RATE = 0x0001U,
PA_RESAMPLER_NO_REMAP = 0x0002U, /* implies NO_REMIX */
PA_RESAMPLER_NO_REMIX = 0x0004U,
- PA_RESAMPLER_NO_LFE = 0x0008U,
PA_RESAMPLER_NO_FILL_SINK = 0x0010U,
+ PA_RESAMPLER_PRODUCE_LFE = 0x0020U,
+ PA_RESAMPLER_CONSUME_LFE = 0x0040U,
} pa_resample_flags_t;
struct pa_resampler {
diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c
index 98cf88f..1085bf9 100644
--- a/src/pulsecore/rtpoll.c
+++ b/src/pulsecore/rtpoll.c
@@ -77,7 +77,9 @@ struct pa_rtpoll_item {
int (*work_cb)(pa_rtpoll_item *i);
int (*before_cb)(pa_rtpoll_item *i);
void (*after_cb)(pa_rtpoll_item *i);
- void *userdata;
+ void *work_userdata;
+ void *before_userdata;
+ void *after_userdata;
PA_LLIST_FIELDS(pa_rtpoll_item);
};
@@ -411,7 +413,9 @@ pa_rtpoll_item *pa_rtpoll_item_new(pa_rtpoll *p, pa_rtpoll_priority_t prio, unsi
i->pollfd = NULL;
i->priority = prio;
- i->userdata = NULL;
+ i->work_userdata = NULL;
+ i->before_userdata = NULL;
+ i->work_userdata = NULL;
i->before_cb = NULL;
i->after_cb = NULL;
i->work_cb = NULL;
@@ -458,42 +462,39 @@ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds) {
return i->pollfd;
}
-void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i)) {
+void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i), void *userdata) {
pa_assert(i);
pa_assert(i->priority < PA_RTPOLL_NEVER);
i->before_cb = before_cb;
+ i->before_userdata = userdata;
}
-void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i)) {
+void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i), void *userdata) {
pa_assert(i);
pa_assert(i->priority < PA_RTPOLL_NEVER);
i->after_cb = after_cb;
+ i->after_userdata = userdata;
}
-void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i)) {
+void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i), void *userdata) {
pa_assert(i);
pa_assert(i->priority < PA_RTPOLL_NEVER);
i->work_cb = work_cb;
+ i->work_userdata = userdata;
}
-void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata) {
+void* pa_rtpoll_item_get_work_userdata(pa_rtpoll_item *i) {
pa_assert(i);
- i->userdata = userdata;
-}
-
-void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i) {
- pa_assert(i);
-
- return i->userdata;
+ return i->work_userdata;
}
static int fdsem_before(pa_rtpoll_item *i) {
- if (pa_fdsem_before_poll(i->userdata) < 0)
+ if (pa_fdsem_before_poll(i->before_userdata) < 0)
return 1; /* 1 means immediate restart of the loop */
return 0;
@@ -503,7 +504,7 @@ static void fdsem_after(pa_rtpoll_item *i) {
pa_assert(i);
pa_assert((i->pollfd[0].revents & ~POLLIN) == 0);
- pa_fdsem_after_poll(i->userdata);
+ pa_fdsem_after_poll(i->after_userdata);
}
pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *f) {
@@ -520,9 +521,8 @@ pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio
pollfd->fd = pa_fdsem_get(f);
pollfd->events = POLLIN;
- i->before_cb = fdsem_before;
- i->after_cb = fdsem_after;
- i->userdata = f;
+ pa_rtpoll_item_set_before_callback(i, fdsem_before, f);
+ pa_rtpoll_item_set_after_callback(i, fdsem_after, f);
return i;
}
@@ -530,7 +530,7 @@ pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio
static int asyncmsgq_read_before(pa_rtpoll_item *i) {
pa_assert(i);
- if (pa_asyncmsgq_read_before_poll(i->userdata) < 0)
+ if (pa_asyncmsgq_read_before_poll(i->before_userdata) < 0)
return 1; /* 1 means immediate restart of the loop */
return 0;
@@ -540,7 +540,7 @@ static void asyncmsgq_read_after(pa_rtpoll_item *i) {
pa_assert(i);
pa_assert((i->pollfd[0].revents & ~POLLIN) == 0);
- pa_asyncmsgq_read_after_poll(i->userdata);
+ pa_asyncmsgq_read_after_poll(i->after_userdata);
}
static int asyncmsgq_read_work(pa_rtpoll_item *i) {
@@ -552,11 +552,11 @@ static int asyncmsgq_read_work(pa_rtpoll_item *i) {
pa_assert(i);
- if (pa_asyncmsgq_get(i->userdata, &object, &code, &data, &offset, &chunk, 0) == 0) {
+ if (pa_asyncmsgq_get(i->work_userdata, &object, &code, &data, &offset, &chunk, 0) == 0) {
int ret;
if (!object && code == PA_MESSAGE_SHUTDOWN) {
- pa_asyncmsgq_done(i->userdata, 0);
+ pa_asyncmsgq_done(i->work_userdata, 0);
/* Requests the loop to exit. Will cause the next iteration of
* pa_rtpoll_run() to return 0 */
i->rtpoll->quit = true;
@@ -564,7 +564,7 @@ static int asyncmsgq_read_work(pa_rtpoll_item *i) {
}
ret = pa_asyncmsgq_dispatch(object, code, data, offset, &chunk);
- pa_asyncmsgq_done(i->userdata, ret);
+ pa_asyncmsgq_done(i->work_userdata, ret);
return 1;
}
@@ -584,10 +584,9 @@ pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll *p, pa_rtpoll_priori
pollfd->fd = pa_asyncmsgq_read_fd(q);
pollfd->events = POLLIN;
- i->before_cb = asyncmsgq_read_before;
- i->after_cb = asyncmsgq_read_after;
- i->work_cb = asyncmsgq_read_work;
- i->userdata = q;
+ pa_rtpoll_item_set_before_callback(i, asyncmsgq_read_before, q);
+ pa_rtpoll_item_set_after_callback(i, asyncmsgq_read_after, q);
+ pa_rtpoll_item_set_work_callback(i, asyncmsgq_read_work, q);
return i;
}
@@ -595,7 +594,7 @@ pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll *p, pa_rtpoll_priori
static int asyncmsgq_write_before(pa_rtpoll_item *i) {
pa_assert(i);
- pa_asyncmsgq_write_before_poll(i->userdata);
+ pa_asyncmsgq_write_before_poll(i->before_userdata);
return 0;
}
@@ -603,7 +602,7 @@ static void asyncmsgq_write_after(pa_rtpoll_item *i) {
pa_assert(i);
pa_assert((i->pollfd[0].revents & ~POLLIN) == 0);
- pa_asyncmsgq_write_after_poll(i->userdata);
+ pa_asyncmsgq_write_after_poll(i->after_userdata);
}
pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q) {
@@ -619,10 +618,8 @@ pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll *p, pa_rtpoll_prior
pollfd->fd = pa_asyncmsgq_write_fd(q);
pollfd->events = POLLIN;
- i->before_cb = asyncmsgq_write_before;
- i->after_cb = asyncmsgq_write_after;
- i->work_cb = NULL;
- i->userdata = q;
+ pa_rtpoll_item_set_before_callback(i, asyncmsgq_write_before, q);
+ pa_rtpoll_item_set_after_callback(i, asyncmsgq_write_after, q);
return i;
}
diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h
index 8f0715a..121b51e 100644
--- a/src/pulsecore/rtpoll.h
+++ b/src/pulsecore/rtpoll.h
@@ -80,19 +80,18 @@ struct pollfd *pa_rtpoll_item_get_pollfd(pa_rtpoll_item *i, unsigned *n_fds);
/* Set the callback that shall be called when there's time to do some work: If the
* callback returns a value > 0, the poll is skipped and the next
* iteration of the loop will start immediately. */
-void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i));
+void pa_rtpoll_item_set_work_callback(pa_rtpoll_item *i, int (*work_cb)(pa_rtpoll_item *i), void *userdata);
/* Set the callback that shall be called immediately before entering
* the sleeping poll: If the callback returns a value > 0, the poll is
* skipped and the next iteration of the loop will start immediately. */
-void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i));
+void pa_rtpoll_item_set_before_callback(pa_rtpoll_item *i, int (*before_cb)(pa_rtpoll_item *i), void *userdata);
/* Set the callback that shall be called immediately after having
* entered the sleeping poll */
-void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i));
+void pa_rtpoll_item_set_after_callback(pa_rtpoll_item *i, void (*after_cb)(pa_rtpoll_item *i), void *userdata);
-void pa_rtpoll_item_set_userdata(pa_rtpoll_item *i, void *userdata);
-void* pa_rtpoll_item_get_userdata(pa_rtpoll_item *i);
+void* pa_rtpoll_item_get_work_userdata(pa_rtpoll_item *i);
pa_rtpoll_item *pa_rtpoll_item_new_fdsem(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_fdsem *s);
pa_rtpoll_item *pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll *p, pa_rtpoll_priority_t prio, pa_asyncmsgq *q);
diff --git a/src/pulsecore/sink-input.c b/src/pulsecore/sink-input.c
index d3ead2c..12e3c8b 100644
--- a/src/pulsecore/sink-input.c
+++ b/src/pulsecore/sink-input.c
@@ -190,7 +190,10 @@ bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, b
if (!data->req_formats) {
/* We're not working with the extended API */
data->sink = s;
- data->save_sink = save;
+ if (save) {
+ pa_xfree(data->preferred_sink);
+ data->preferred_sink = pa_xstrdup(s->name);
+ }
data->sink_requested_by_application = requested_by_application;
} else {
/* Extended API: let's see if this sink supports the formats the client can provide */
@@ -199,7 +202,10 @@ bool pa_sink_input_new_data_set_sink(pa_sink_input_new_data *data, pa_sink *s, b
if (formats && !pa_idxset_isempty(formats)) {
/* Sink supports at least one of the requested formats */
data->sink = s;
- data->save_sink = save;
+ if (save) {
+ pa_xfree(data->preferred_sink);
+ data->preferred_sink = pa_xstrdup(s->name);
+ }
data->sink_requested_by_application = requested_by_application;
if (data->nego_formats)
pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
@@ -226,7 +232,7 @@ bool pa_sink_input_new_data_set_formats(pa_sink_input_new_data *data, pa_idxset
if (data->sink) {
/* Trigger format negotiation */
- return pa_sink_input_new_data_set_sink(data, data->sink, data->save_sink, data->sink_requested_by_application);
+ return pa_sink_input_new_data_set_sink(data, data->sink, (data->preferred_sink != NULL), data->sink_requested_by_application);
}
return true;
@@ -250,6 +256,9 @@ void pa_sink_input_new_data_done(pa_sink_input_new_data *data) {
if (data->volume_factor_sink_items)
pa_hashmap_free(data->volume_factor_sink_items);
+ if (data->preferred_sink)
+ pa_xfree(data->preferred_sink);
+
pa_proplist_free(data->proplist);
}
@@ -467,7 +476,8 @@ int pa_sink_input_new(
((data->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
(core->disable_remixing || (data->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
(core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
- (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
+ (core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
+ (core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return -PA_ERR_NOTSUPPORTED;
}
@@ -518,7 +528,7 @@ int pa_sink_input_new(
pa_cvolume_reset(&i->real_ratio, i->sample_spec.channels);
i->volume_writable = data->volume_writable;
i->save_volume = data->save_volume;
- i->save_sink = data->save_sink;
+ i->preferred_sink = pa_xstrdup(data->preferred_sink);
i->save_muted = data->save_muted;
i->muted = data->muted;
@@ -776,6 +786,9 @@ static void sink_input_free(pa_object *o) {
if (i->volume_factor_sink_items)
pa_hashmap_free(i->volume_factor_sink_items);
+ if (i->preferred_sink)
+ pa_xfree(i->preferred_sink);
+
pa_xfree(i->driver);
pa_xfree(i);
}
@@ -1914,7 +1927,16 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, bool save) {
i->moving(i, dest);
i->sink = dest;
- i->save_sink = save;
+ /* save == true, means user is calling the move_to() and want to
+ save the preferred_sink */
+ if (save) {
+ pa_xfree(i->preferred_sink);
+ if (dest == dest->core->default_sink)
+ i->preferred_sink = NULL;
+ else
+ i->preferred_sink = pa_xstrdup(dest->name);
+ }
+
pa_idxset_put(dest->inputs, pa_sink_input_ref(i), NULL);
PA_HASHMAP_FOREACH(v, i->volume_factor_sink_items, state)
@@ -1957,6 +1979,12 @@ void pa_sink_input_fail_move(pa_sink_input *i) {
if (pa_hook_fire(&i->core->hooks[PA_CORE_HOOK_SINK_INPUT_MOVE_FAIL], i) == PA_HOOK_STOP)
return;
+ /* Can we move the sink input to the default sink? */
+ if (i->core->rescue_streams && pa_sink_input_may_move_to(i, i->core->default_sink)) {
+ if (pa_sink_input_finish_move(i, i->core->default_sink, false) >= 0)
+ return;
+ }
+
if (i->moving)
i->moving(i, NULL);
@@ -2292,7 +2320,8 @@ int pa_sink_input_update_resampler(pa_sink_input *i) {
((i->flags & PA_SINK_INPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
(i->core->disable_remixing || (i->flags & PA_SINK_INPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
(i->core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
- (i->core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0));
+ (i->core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
+ (i->core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0));
if (!new_resampler) {
pa_log_warn("Unsupported resampling operation.");
@@ -2404,3 +2433,17 @@ void pa_sink_input_set_reference_ratio(pa_sink_input *i, const pa_cvolume *ratio
pa_cvolume_snprint_verbose(old_ratio_str, sizeof(old_ratio_str), &old_ratio, &i->channel_map, true),
pa_cvolume_snprint_verbose(new_ratio_str, sizeof(new_ratio_str), ratio, &i->channel_map, true));
}
+
+/* Called from the main thread. */
+void pa_sink_input_set_preferred_sink(pa_sink_input *i, pa_sink *s) {
+ pa_assert(i);
+
+ pa_xfree(i->preferred_sink);
+ if (s) {
+ i->preferred_sink = pa_xstrdup(s->name);
+ pa_sink_input_move_to(i, s, false);
+ } else {
+ i->preferred_sink = NULL;
+ pa_sink_input_move_to(i, i->core->default_sink, false);
+ }
+}
diff --git a/src/pulsecore/sink-input.h b/src/pulsecore/sink-input.h
index f7f9237..d3de6e3 100644
--- a/src/pulsecore/sink-input.h
+++ b/src/pulsecore/sink-input.h
@@ -119,11 +119,16 @@ struct pa_sink_input {
bool muted:1;
- /* if true then the sink we are connected to and/or the volume
- * set is worth remembering, i.e. was explicitly chosen by the
- * user and not automatically. module-stream-restore looks for
+ /* if true then the volume and the mute state of this sink-input
+ * are worth remembering, module-stream-restore looks for
* this.*/
- bool save_sink:1, save_volume:1, save_muted:1;
+ bool save_volume:1, save_muted:1;
+
+ /* if users move the sink-input to a sink, and the sink is not default_sink,
+ * the sink->name will be saved in preferred_sink. And later if sink-input
+ * is moved to other sinks for some reason, it still can be restored to the
+ * preferred_sink at an appropriate time */
+ char *preferred_sink;
pa_resample_method_t requested_resample_method, actual_resample_method;
@@ -315,7 +320,9 @@ typedef struct pa_sink_input_new_data {
bool volume_writable:1;
- bool save_sink:1, save_volume:1, save_muted:1;
+ bool save_volume:1, save_muted:1;
+
+ char *preferred_sink;
} pa_sink_input_new_data;
pa_sink_input_new_data* pa_sink_input_new_data_init(pa_sink_input_new_data *data);
@@ -454,6 +461,8 @@ void pa_sink_input_set_volume_direct(pa_sink_input *i, const pa_cvolume *volume)
* i->reference_ratio and logs a message if the value changes. */
void pa_sink_input_set_reference_ratio(pa_sink_input *i, const pa_cvolume *ratio);
+void pa_sink_input_set_preferred_sink(pa_sink_input *i, pa_sink *s);
+
#define pa_sink_input_assert_io_context(s) \
pa_assert(pa_thread_mq_get() || !PA_SINK_INPUT_IS_LINKED((s)->state))
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index 55e9af3..11c3849 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -724,9 +724,14 @@ void pa_sink_put(pa_sink* s) {
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index);
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PUT], s);
- /* This function must be called after the PA_CORE_HOOK_SINK_PUT hook,
- * because module-switch-on-connect needs to know the old default sink */
+ /* It's good to fire the SINK_PUT hook before updating the default sink,
+ * because module-switch-on-connect will set the new sink as the default
+ * sink, and if we were to call pa_core_update_default_sink() before that,
+ * the default sink might change twice, causing unnecessary stream moving. */
+
pa_core_update_default_sink(s->core);
+
+ pa_core_move_streams_to_newly_available_preferred_sink(s->core, s);
}
/* Called from main context */
@@ -757,6 +762,9 @@ void pa_sink_unlink(pa_sink* s) {
pa_core_update_default_sink(s->core);
+ if (linked && s->core->rescue_streams)
+ pa_sink_move_streams_to_default_sink(s->core, s, false);
+
if (s->card)
pa_idxset_remove_by_data(s->card->sinks, s, NULL);
@@ -3931,3 +3939,44 @@ void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume) {
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_VOLUME_CHANGED], s);
}
+
+void pa_sink_move_streams_to_default_sink(pa_core *core, pa_sink *old_sink, bool default_sink_changed) {
+ pa_sink_input *i;
+ uint32_t idx;
+
+ pa_assert(core);
+ pa_assert(old_sink);
+
+ if (core->state == PA_CORE_SHUTDOWN)
+ return;
+
+ if (core->default_sink == NULL || core->default_sink->unlink_requested)
+ return;
+
+ if (old_sink == core->default_sink)
+ return;
+
+ PA_IDXSET_FOREACH(i, old_sink->inputs, idx) {
+ if (!PA_SINK_INPUT_IS_LINKED(i->state))
+ continue;
+
+ if (!i->sink)
+ continue;
+
+ /* If default_sink_changed is false, the old sink became unavailable, so all streams must be moved. */
+ if (pa_safe_streq(old_sink->name, i->preferred_sink) && default_sink_changed)
+ continue;
+
+ if (!pa_sink_input_may_move_to(i, core->default_sink))
+ continue;
+
+ if (default_sink_changed)
+ pa_log_info("The sink input %u \"%s\" is moving to %s due to change of the default sink.",
+ i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), core->default_sink->name);
+ else
+ pa_log_info("The sink input %u \"%s\" is moving to %s, because the old sink became unavailable.",
+ i->index, pa_strnull(pa_proplist_gets(i->proplist, PA_PROP_APPLICATION_NAME)), core->default_sink->name);
+
+ pa_sink_input_move_to(i, core->default_sink, false);
+ }
+}
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index b9dd64f..1778eb7 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -558,6 +558,12 @@ int64_t pa_sink_get_latency_within_thread(pa_sink *s, bool allow_negative);
* s->reference_volume and fires change notifications. */
void pa_sink_set_reference_volume_direct(pa_sink *s, const pa_cvolume *volume);
+/* When the default_sink is changed or the active_port of a sink is changed to
+ * PA_AVAILABLE_NO, this function is called to move the streams of the old
+ * default_sink or the sink with active_port equals PA_AVAILABLE_NO to the
+ * current default_sink conditionally*/
+void pa_sink_move_streams_to_default_sink(pa_core *core, pa_sink *old_sink, bool default_sink_changed);
+
/* Verify that we called in IO context (aka 'thread context), or that
* the sink is not yet set up, i.e. the thread not set up yet. See
* pa_assert_io_context() in thread-mq.h for more information. */
diff --git a/src/pulsecore/source-output.c b/src/pulsecore/source-output.c
index f5005ab..92f74d4 100644
--- a/src/pulsecore/source-output.c
+++ b/src/pulsecore/source-output.c
@@ -134,7 +134,10 @@ bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_so
if (!data->req_formats) {
/* We're not working with the extended API */
data->source = s;
- data->save_source = save;
+ if (save) {
+ pa_xfree(data->preferred_source);
+ data->preferred_source = pa_xstrdup(s->name);
+ }
data->source_requested_by_application = requested_by_application;
} else {
/* Extended API: let's see if this source supports the formats the client would like */
@@ -143,7 +146,10 @@ bool pa_source_output_new_data_set_source(pa_source_output_new_data *data, pa_so
if (formats && !pa_idxset_isempty(formats)) {
/* Source supports at least one of the requested formats */
data->source = s;
- data->save_source = save;
+ if (save) {
+ pa_xfree(data->preferred_source);
+ data->preferred_source = pa_xstrdup(s->name);
+ }
data->source_requested_by_application = requested_by_application;
if (data->nego_formats)
pa_idxset_free(data->nego_formats, (pa_free_cb_t) pa_format_info_free);
@@ -170,7 +176,7 @@ bool pa_source_output_new_data_set_formats(pa_source_output_new_data *data, pa_i
if (data->source) {
/* Trigger format negotiation */
- return pa_source_output_new_data_set_source(data, data->source, data->save_source,
+ return pa_source_output_new_data_set_source(data, data->source, (data->preferred_source != NULL),
data->source_requested_by_application);
}
@@ -189,6 +195,9 @@ void pa_source_output_new_data_done(pa_source_output_new_data *data) {
if (data->format)
pa_format_info_free(data->format);
+ if (data->preferred_source)
+ pa_xfree(data->preferred_source);
+
pa_proplist_free(data->proplist);
}
@@ -414,7 +423,8 @@ int pa_source_output_new(
((data->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
(core->disable_remixing || (data->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
(core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
- (core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0)))) {
+ (core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
+ (core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0)))) {
pa_log_warn("Unsupported resampling operation.");
return -PA_ERR_NOTSUPPORTED;
}
@@ -459,7 +469,7 @@ int pa_source_output_new(
pa_cvolume_reset(&o->real_ratio, o->sample_spec.channels);
o->volume_writable = data->volume_writable;
o->save_volume = data->save_volume;
- o->save_source = data->save_source;
+ o->preferred_source = pa_xstrdup(data->preferred_source);
o->save_muted = data->save_muted;
o->muted = data->muted;
@@ -651,6 +661,9 @@ static void source_output_free(pa_object* mo) {
if (o->proplist)
pa_proplist_free(o->proplist);
+ if (o->preferred_source)
+ pa_xfree(o->preferred_source);
+
pa_xfree(o->driver);
pa_xfree(o);
}
@@ -1544,7 +1557,16 @@ int pa_source_output_finish_move(pa_source_output *o, pa_source *dest, bool save
o->moving(o, dest);
o->source = dest;
- o->save_source = save;
+ /* save == true, means user is calling the move_to() and want to
+ save the preferred_source */
+ if (save) {
+ pa_xfree(o->preferred_source);
+ if (dest == dest->core->default_source)
+ o->preferred_source = NULL;
+ else
+ o->preferred_source = pa_xstrdup(dest->name);
+ }
+
pa_idxset_put(o->source->outputs, pa_source_output_ref(o), NULL);
pa_cvolume_remap(&o->volume_factor_source, &o->channel_map, &o->source->channel_map);
@@ -1584,6 +1606,12 @@ void pa_source_output_fail_move(pa_source_output *o) {
if (pa_hook_fire(&o->core->hooks[PA_CORE_HOOK_SOURCE_OUTPUT_MOVE_FAIL], o) == PA_HOOK_STOP)
return;
+ /* Can we move the source output to the default source? */
+ if (o->core->rescue_streams && pa_source_output_may_move_to(o, o->core->default_source)) {
+ if (pa_source_output_finish_move(o, o->core->default_source, false) >= 0)
+ return;
+ }
+
if (o->moving)
o->moving(o, NULL);
@@ -1755,7 +1783,8 @@ int pa_source_output_update_resampler(pa_source_output *o) {
((o->flags & PA_SOURCE_OUTPUT_NO_REMAP) ? PA_RESAMPLER_NO_REMAP : 0) |
(o->core->disable_remixing || (o->flags & PA_SOURCE_OUTPUT_NO_REMIX) ? PA_RESAMPLER_NO_REMIX : 0) |
(o->core->remixing_use_all_sink_channels ? 0 : PA_RESAMPLER_NO_FILL_SINK) |
- (o->core->disable_lfe_remixing ? PA_RESAMPLER_NO_LFE : 0));
+ (o->core->remixing_produce_lfe ? PA_RESAMPLER_PRODUCE_LFE : 0) |
+ (o->core->remixing_consume_lfe ? PA_RESAMPLER_CONSUME_LFE : 0));
if (!new_resampler) {
pa_log_warn("Unsupported resampling operation.");
@@ -1867,3 +1896,17 @@ void pa_source_output_set_reference_ratio(pa_source_output *o, const pa_cvolume
pa_cvolume_snprint_verbose(old_ratio_str, sizeof(old_ratio_str), &old_ratio, &o->channel_map, true),
pa_cvolume_snprint_verbose(new_ratio_str, sizeof(new_ratio_str), ratio, &o->channel_map, true));
}
+
+/* Called from the main thread. */
+void pa_source_output_set_preferred_source(pa_source_output *o, pa_source *s) {
+ pa_assert(o);
+
+ pa_xfree(o->preferred_source);
+ if (s) {
+ o->preferred_source = pa_xstrdup(s->name);
+ pa_source_output_move_to(o, s, false);
+ } else {
+ o->preferred_source = NULL;
+ pa_source_output_move_to(o, o->core->default_source, false);
+ }
+}
diff --git a/src/pulsecore/source-output.h b/src/pulsecore/source-output.h
index 16853c0..2bf5682 100644
--- a/src/pulsecore/source-output.h
+++ b/src/pulsecore/source-output.h
@@ -106,11 +106,15 @@ struct pa_source_output {
bool muted:1;
- /* if true then the source we are connected to and/or the volume
- * set is worth remembering, i.e. was explicitly chosen by the
- * user and not automatically. module-stream-restore looks for
- * this.*/
- bool save_source:1, save_volume:1, save_muted:1;
+ /* if true then the volume and the mute state of this source-output
+ * are worth remembering, module-stream-restore looks for this. */
+ bool save_volume:1, save_muted:1;
+
+ /* if users move the source-output to a source, and the source is not
+ * default_source, the source->name will be saved in preferred_source. And
+ * later if source-output is moved to other sources for some reason, it
+ * still can be restored to the preferred_source at an appropriate time */
+ char *preferred_source;
pa_resample_method_t requested_resample_method, actual_resample_method;
@@ -277,7 +281,8 @@ typedef struct pa_source_output_new_data {
bool volume_writable:1;
- bool save_source:1, save_volume:1, save_muted:1;
+ bool save_volume:1, save_muted:1;
+ char *preferred_source;
} pa_source_output_new_data;
pa_source_output_new_data* pa_source_output_new_data_init(pa_source_output_new_data *data);
@@ -397,6 +402,8 @@ void pa_source_output_set_volume_direct(pa_source_output *o, const pa_cvolume *v
* o->reference_ratio and logs a message if the value changes. */
void pa_source_output_set_reference_ratio(pa_source_output *o, const pa_cvolume *ratio);
+void pa_source_output_set_preferred_source(pa_source_output *o, pa_source *s);
+
#define pa_source_output_assert_io_context(s) \
pa_assert(pa_thread_mq_get() || !PA_SOURCE_OUTPUT_IS_LINKED((s)->state))
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 855d3de..1cb83f9 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -666,9 +666,13 @@ void pa_source_put(pa_source *s) {
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index);
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PUT], s);
- /* This function must be called after the PA_CORE_HOOK_SOURCE_PUT hook,
- * because module-switch-on-connect needs to know the old default source */
+ /* It's good to fire the SOURCE_PUT hook before updating the default source,
+ * because module-switch-on-connect will set the new source as the default
+ * source, and if we were to call pa_core_update_default_source() before that,
+ * the default source might change twice, causing unnecessary stream moving. */
pa_core_update_default_source(s->core);
+
+ pa_core_move_streams_to_newly_available_preferred_source(s->core, s);
}
/* Called from main context */
@@ -698,6 +702,9 @@ void pa_source_unlink(pa_source *s) {
pa_core_update_default_source(s->core);
+ if (linked && s->core->rescue_streams)
+ pa_source_move_streams_to_default_source(s->core, s, false);
+
if (s->card)
pa_idxset_remove_by_data(s->card->sources, s, NULL);
@@ -2988,3 +2995,44 @@ void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volum
pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index);
pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_VOLUME_CHANGED], s);
}
+
+void pa_source_move_streams_to_default_source(pa_core *core, pa_source *old_source, bool default_source_changed) {
+ pa_source_output *o;
+ uint32_t idx;
+
+ pa_assert(core);
+ pa_assert(old_source);
+
+ if (core->state == PA_CORE_SHUTDOWN)
+ return;
+
+ if (core->default_source == NULL || core->default_source->unlink_requested)
+ return;
+
+ if (old_source == core->default_source)
+ return;
+
+ PA_IDXSET_FOREACH(o, old_source->outputs, idx) {
+ if (!PA_SOURCE_OUTPUT_IS_LINKED(o->state))
+ continue;
+
+ if (!o->source)
+ continue;
+
+ /* If default_source_changed is false, the old source became unavailable, so all streams must be moved. */
+ if (pa_safe_streq(old_source->name, o->preferred_source) && default_source_changed)
+ continue;
+
+ if (!pa_source_output_may_move_to(o, core->default_source))
+ continue;
+
+ if (default_source_changed)
+ pa_log_info("The source output %u \"%s\" is moving to %s due to change of the default source.",
+ o->index, pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), core->default_source->name);
+ else
+ pa_log_info("The source output %u \"%s\" is moving to %s, because the old source became unavailable.",
+ o->index, pa_strnull(pa_proplist_gets(o->proplist, PA_PROP_APPLICATION_NAME)), core->default_source->name);
+
+ pa_source_output_move_to(o, core->default_source, false);
+ }
+}
diff --git a/src/pulsecore/source.h b/src/pulsecore/source.h
index e9462c6..12e37d6 100644
--- a/src/pulsecore/source.h
+++ b/src/pulsecore/source.h
@@ -479,6 +479,12 @@ int64_t pa_source_get_latency_within_thread(pa_source *s, bool allow_negative);
* sets s->reference_volume and fires change notifications. */
void pa_source_set_reference_volume_direct(pa_source *s, const pa_cvolume *volume);
+/* When the default_source is changed or the active_port of a source is changed to
+ * PA_AVAILABLE_NO, this function is called to move the streams of the old
+ * default_source or the source with active_port equals PA_AVAILABLE_NO to the
+ * current default_source conditionally*/
+void pa_source_move_streams_to_default_source(pa_core *core, pa_source *old_source, bool default_source_changed);
+
#define pa_source_assert_io_context(s) \
pa_assert(pa_thread_mq_get() || !PA_SOURCE_IS_LINKED((s)->state))
diff --git a/src/tests/alsa-mixer-path-test.c b/src/tests/alsa-mixer-path-test.c
index ee40587..75cf086 100644
--- a/src/tests/alsa-mixer-path-test.c
+++ b/src/tests/alsa-mixer-path-test.c
@@ -13,6 +13,10 @@
#include <pulsecore/strlist.h>
#include <modules/alsa/alsa-mixer.h>
+/* This test inspects the Makefile, so this is not applicable when using
+ * Meson. */
+#ifndef MESON_BUILD
+
/* This function was copied from alsa-mixer.c */
static const char *get_default_paths_dir(void) {
if (pa_run_from_build_tree())
@@ -52,6 +56,7 @@ static pa_strlist *load_makefile() {
fclose(f);
return result;
}
+#endif /* end of #ifndef MESON_BUILD */
START_TEST (mixer_path_test) {
#ifdef MESON_BUILD
diff --git a/src/tests/meson.build b/src/tests/meson.build
index 621c2c9..643a08d 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -53,7 +53,7 @@ default_tests = [
[ 'queue-test', 'queue-test.c',
[ check_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep ] ],
[ 'resampler-test', 'resampler-test.c',
- [ libpulse_dep, libpulsecommon_dep, libpulsecore_dep ] ],
+ [ libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libintl_dep ] ],
[ 'rtpoll-test', 'rtpoll-test.c',
[ check_dep, libpulse_dep, libpulsecommon_dep, libpulsecore_dep ] ],
[ 'smoother-test', 'smoother-test.c',
@@ -143,7 +143,7 @@ echo_cancel_test_sources += module_echo_cancel_orc_sources
norun_tests += [
[ 'echo-cancel-test', echo_cancel_test_sources,
- module_echo_cancel_deps + [ libpulse_dep, libpulsecommon_dep, libpulsecore_dep ],
+ module_echo_cancel_deps + [ libpulse_dep, libpulsecommon_dep, libpulsecore_dep, libintl_dep ],
module_echo_cancel_libs,
module_echo_cancel_flags + server_c_args + [ '-DPA_MODULE_NAME=module_echo_cancel', '-DECHO_CANCEL_TEST=1' ] ]
]
diff --git a/src/tests/remix-test.c b/src/tests/remix-test.c
index 0dcc2f1..8e1292d 100644
--- a/src/tests/remix-test.c
+++ b/src/tests/remix-test.c
@@ -33,7 +33,7 @@ struct resample_flags {
};
/* Call like this to get an initializer for struct resample_flags:
- * RESAMPLE_FLAGS(PA_RESAMPLER_NO_LFE)
+ * RESAMPLE_FLAGS(PA_RESAMPLER_PRODUCE_LFE)
*/
#define RESAMPLE_FLAGS(flags) { .str = #flags, .value = (flags) }
@@ -60,9 +60,13 @@ int main(int argc, char *argv[]) {
RESAMPLE_FLAGS(0),
RESAMPLE_FLAGS(PA_RESAMPLER_NO_REMAP),
RESAMPLE_FLAGS(PA_RESAMPLER_NO_REMIX),
- RESAMPLE_FLAGS(PA_RESAMPLER_NO_LFE),
+ RESAMPLE_FLAGS(PA_RESAMPLER_PRODUCE_LFE),
RESAMPLE_FLAGS(PA_RESAMPLER_NO_FILL_SINK),
- RESAMPLE_FLAGS(PA_RESAMPLER_NO_LFE | PA_RESAMPLER_NO_FILL_SINK),
+ RESAMPLE_FLAGS(PA_RESAMPLER_PRODUCE_LFE | PA_RESAMPLER_NO_FILL_SINK),
+ RESAMPLE_FLAGS(PA_RESAMPLER_CONSUME_LFE),
+ RESAMPLE_FLAGS(PA_RESAMPLER_CONSUME_LFE | PA_RESAMPLER_NO_FILL_SINK),
+ RESAMPLE_FLAGS(PA_RESAMPLER_PRODUCE_LFE | PA_RESAMPLER_CONSUME_LFE),
+ RESAMPLE_FLAGS(PA_RESAMPLER_PRODUCE_LFE | PA_RESAMPLER_CONSUME_LFE | PA_RESAMPLER_NO_FILL_SINK),
{ .str = NULL, .value = 0 },
};
diff --git a/src/tests/rtpoll-test.c b/src/tests/rtpoll-test.c
index 24c6619..aab637b 100644
--- a/src/tests/rtpoll-test.c
+++ b/src/tests/rtpoll-test.c
@@ -48,15 +48,15 @@ START_TEST (rtpoll_test) {
p = pa_rtpoll_new();
i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1);
- pa_rtpoll_item_set_before_callback(i, before);
- pa_rtpoll_item_set_after_callback(i, after);
+ pa_rtpoll_item_set_before_callback(i, before, NULL);
+ pa_rtpoll_item_set_after_callback(i, after, NULL);
pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
pollfd->fd = 0;
pollfd->events = POLLIN;
w = pa_rtpoll_item_new(p, PA_RTPOLL_NORMAL, 0);
- pa_rtpoll_item_set_before_callback(w, worker);
+ pa_rtpoll_item_set_before_callback(w, worker, NULL);
pa_rtpoll_set_timer_relative(p, 10000000); /* 10 s */
@@ -65,8 +65,8 @@ START_TEST (rtpoll_test) {
pa_rtpoll_item_free(i);
i = pa_rtpoll_item_new(p, PA_RTPOLL_EARLY, 1);
- pa_rtpoll_item_set_before_callback(i, before);
- pa_rtpoll_item_set_after_callback(i, after);
+ pa_rtpoll_item_set_before_callback(i, before, NULL);
+ pa_rtpoll_item_set_after_callback(i, after, NULL);
pollfd = pa_rtpoll_item_get_pollfd(i, NULL);
pollfd->fd = 0;
diff --git a/src/utils/meson.build b/src/utils/meson.build
index d00e030..dedf4e4 100644
--- a/src/utils/meson.build
+++ b/src/utils/meson.build
@@ -15,7 +15,7 @@ executable('pacat',
install_rpath : privlibdir,
include_directories : [configinc, topinc],
link_with : [libpulsecommon, libpulse],
- dependencies : [sndfile_dep],
+ dependencies : [sndfile_dep, libintl_dep],
c_args : pa_c_args,
)
@@ -36,7 +36,7 @@ executable('pactl',
install_rpath : privlibdir,
include_directories : [configinc, topinc],
link_with : [libpulsecommon, libpulse],
- dependencies : [sndfile_dep],
+ dependencies : [sndfile_dep, libintl_dep],
c_args : pa_c_args,
)
@@ -50,6 +50,7 @@ executable('pasuspender',
install_rpath : privlibdir,
include_directories : [configinc, topinc],
link_with : [libpulsecommon, libpulse],
+ dependencies: [libintl_dep],
c_args : pa_c_args,
)
@@ -63,6 +64,7 @@ executable('pacmd',
install_rpath : privlibdir,
include_directories : [configinc, topinc],
link_with : [libpulsecommon, libpulse],
+ dependencies: [libintl_dep],
c_args : pa_c_args,
)
@@ -77,7 +79,7 @@ if x11_dep.found()
install_rpath : privlibdir,
include_directories : [configinc, topinc],
link_with : [libpulsecommon, libpulse],
- dependencies : [x11_dep],
+ dependencies : [x11_dep, libintl_dep],
c_args : pa_c_args,
)
endif
diff --git a/src/utils/qpaeq b/src/utils/qpaeq
index ac0daec..7e01d87 100755
--- a/src/utils/qpaeq
+++ b/src/utils/qpaeq
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# qpaeq is a equalizer interface for pulseaudio's equalizer sinks
# Copyright (C) 2009 Jason Newton <nevion@gmail.com
#
@@ -18,7 +18,6 @@
import os,math,sys
try:
- import PyQt5,sip
from PyQt5 import QtWidgets,QtCore
import dbus.mainloop.pyqt5
import dbus